Setting up Codecov in Susper repository hosted on Github

In this blog post, I’ll be discussing how we setup codecov in Susper.

  • What is Codecov and in what projects it is being used in FOSSASIA?

Codecov is a famous code coverage tool. It can be easily integrated with the services like Travis CI. Codecov also provides more features with the services like Docker.

Projects in FOSSASIA like Open Event Orga Server, Loklak search, Open Event Web App uses Codecov. Recently, in the Susper project also the code coverage tool has been configured.

  • How we setup Codecov in our project repository hosted on Github?

The simplest way to setup Codecov in a project repository is by installing codecov.io using the terminal command:

npm install --save-dev codecov.io

Susper works on tech-stack Angular 2 (we have recently upgraded it to Angular v4.1.3) recently. Angular comes with Karma and Jasmine for testing purpose. There are many repositories of FOSSASIA in which Codecov has been configured like this. But with, Angular this case is a little bit tricky. So, using alone:

bash <(curl -s https://codecov.io/bash)

won’t generate code coverage because of the presence of Karma and Jasmine. It will require two packages: istanbul as coverage reporter and jasmine as html reporter. I have discussed them below.

Install these two packages:

  • Karma-coverage-istanbul-reporter
  • npm install karma-coverage-istanbul-reporter --save-dev
  • Karma-jasmine html reporter
  • npm install karma-jasmine-html-reporter --save-dev

    After installing the codecov.io, the package.json will be updated as follows:

  • "devDependencies": {
      "codecov": "^2.2.0",
      "karma-coverage-istanbul-reporter": "^1.3.0",
      "karma-jasmine-html-reporter": "^0.2.2",
    }

    Add a script for testing:

  • "scripts": {
       "test": "ng test --single-run --code-coverage --reporters=coverage-istanbul"
    }

    Now generally, the codecov works better with Travis CI. With the one line bash <(curl -s https://codecov.io/bash) the code coverage can now be easily reported.

Here is a particular example of travis.yml from the project repository of Susper:

script:
 - ng test --single-run --code-coverage --reporters=coverage-istanbul
 - ng lint
 
after_success:
 - bash <(curl -s https://codecov.io/bash)
 - bash ./deploy.sh

Update karma.config.js as well:

Module.exports = function (config) {
  config.set({
    plugins: [
      require('karma-jasmine-html-reporter'),
      require('karma-coverage-istanbul-reporter')
    ],
    preprocessors: {
      'src/app/**/*.js': ['coverage']
    },
    client {
      clearContext: false
    },
    coverageIstanbulReporter: {
      reports: ['html', 'lcovonly'],
      fixWebpackSourcePaths: true
    },
    reporters: config.angularCli && config.angularCli.codeCoverage
      ? ['progress', 'coverage-istanbul'],
      : ['progress', 'kjhtml'],
  })
}

This karma.config.js is an example from the Susper project. Find out more here: https://github.com/fossasia/susper.com/pull/420
This is how we setup codecov in Susper repository. And like this way, it can be set up in other repositories as well which supports Angular 2 or 4 as tech stack.

Continue ReadingSetting up Codecov in Susper repository hosted on Github

Forms and their validation using Semantic UI in Open Event Frontend

A web form acts as a communication bridge that allows a user to communicate with the organisation and vice versa. In the Open Event project, we need forms so users can contact the organisation, to register themselves, to log into the website, to order a ticket or to query for some information. Here are a few things which were kept in mind before we designed forms in the Open Event Frontend Project:

  • The forms were designed on the principle of keeping it simple which means that it should ask only for the relevant information which is required in actual.
  • They contained the relevant fields ordered in a logical way according to their importance.
  • They offered clear error messages instantly to give direct feedback and allow users to make instant corrections.
  • The clear examples were shown in the front of the field.
  • Proper spacing among the fields was maintained to display proper error messages to the respective form fields.
  • The mandatory fields are highlighted using ‘*’ to avoid confusion.
  • Proper colour combinations have been used to inform the user about the progress while filling the form. For eg. red for any ‘error or incomplete’ information while green signifies ‘correct’.
  • Saving the current data in case the user has to go back to make any corrections later.
  • Allowing to toggle through the form using the keyboard.

The above designing principles helped in avoiding the negative user experience while using the forms.

Let’s take a closer look at the form and the form validation in case of purchase a new ticket form on the Orders page in Open Event Front-end application.

Creating a form

Let’s start by writing some HTML for the form:

<form class="ui form" {{action 'submit' on='submit' }}>
  <div class="ui padded segment">
    <h4 class="ui horizontal divider header">
      <i class="ticket icon"></i>
      {{t 'Ticket Buyer'}}
    </h4>
    <div class="field">
      <label class="required" for="firstname">{{t 'First Name'}}</label>
      {{input type='text' name='first_name' value=buyer.firstName}}
    </div>
    <div class="field">
      <label class="required" for="lastname">{{t 'Last Name'}}</label>
      {{input type='text' name='last_name' value=buyer.lastName}}
    </div>
    <div class="field">
      <label class="required" for="email">{{t 'Email'}}</label>
      {{input type='text' name='email' value=buyer.email}}
    </div>
    <h4 class="ui horizontal divider header">
        <i class="ticket icon"></i>
        {{t 'Ticket Holder\'s Information'}}
    </h4>
    {{#each holders as |holder index|}}
      <div class="inline field">
        <i class="user icon"></i>
         <label>{{t 'Ticket Holder '}}{{inc index}}</label>
      </div>
      <div class="field">
        <label class="required" for="firstname">{{t 'First Name'}}</label>
        {{input type='text' name=(concat 'first_name_' index) value=holder.firstName}}
      </div>
      <div class="field">
        <label class="required" for="lastname">{{t 'Last Name'}}</label>
        {{input type='text' name=(concat 'last_name_' index) value=holder.lastName}}
      </div>
      <div class="field">
        <label class="required" for="email">{{t 'Email'}}</label>
        {{input type='text' name=(concat 'email_' index) value=holder.email}}
      </div>
      <div class="field">
        {{ui-checkbox label=(t 'Same as Ticket Buyer') checked=holder.sameAsBuyer onChange=(action 'fillHolderData' holder)}}
      </div>
    {{/each}}
    <p>
      {{t 'By clicking "Pay Now", I acknowledge that I have read and agree with the Open Event terms of services and privacy policy.'}}
    </p>
    <div class="center aligned">
      <button type="submit" class="ui teal submit button">{{t 'Pay Now'}}</button>
    </div>
  </div>
</form>

 

The complete code for the form can be seen here.

In the above code, we have used Semantic UI elements like button, input, label, icon, header and modules like dropdown, checkbox to create the basic structure of the form.

The form is created using the Semantic markup. Along with semantic UI collection “form”, the segment element has been used to create the grouping of similar content like we have a timer and its related description that after 10 minutes the reservation will no longer be held are put together in a segment where they are arranged using semantic UI view “statistic”. Due to the vastness of semantic UI, all the styling has been done using it like fields inlining, button styling, segment background coloring etc.

The form is created using the Semantic markup. Along with semantic UI collection “form”, the segment element has been used to create the grouping of similar content like we have a timer and its related description that after 10 minutes the reservation will no longer be held are put together in a segment where they are arranged using semantic UI view “statistic”. Semantic UI elements like button, input, label, icon, header and modules like dropdown, checkbox have been used. Due to the vastness of semantic UI, all the styling has been done using it like fields inlining, button styling, segment background colouring etc.

The page for the above HTML code looks like this:

Image for the order form

Fig. 1: Order Form to purchase a ticket

The complete form can be seen on this link.

Adding form validations

We can also add validation in HTML format but writing the validation in JavaScript file is considered good practice.

Let’s see how we can add validation to fields in Javascript.

  getValidationRules() {
    let firstNameValidation = {
      rules: [
        {
          type   : 'empty',
          prompt : this.i18n.t('Please enter your first name')
        }
      ]
    };
    let lastNameValidation = {
      rules: [
        {
          type   : 'empty',
          prompt : this.i18n.t('Please enter your last name')
        }
      ]
    };
    let emailValidation = {
      rules: [
        {
          type   : 'empty',
          prompt : this.i18n.t('Please enter your email')
        }
      ]
    };
    let validationRules = {
      inline : true,
      delay  : false,
      on     : 'blur',
      fields : {
        firstName: {
          identifier : 'first_name',
          rules      : [
            {
              type   : 'empty',
              prompt : this.i18n.t('Please enter your first name')
            }
          ]
        },
        lastName: {
          identifier : 'last_name',
          rules      : [
            {
              type   : 'empty',
              prompt : this.i18n.t('Please enter your last name')
            }
          ]
        },
        email: {
          identifier : 'email',
          rules      : [
            {
              type   : 'email',
              prompt : this.i18n.t('Please enter a valid email address')
            }
          ]
        },
        zipCode: {
          identifier : 'zip_code',
          rules   : [
            {
              type   : 'empty',
              prompt : this.i18n.t('Please enter your zip code')
            }
          ]
        } 
    };

Let’s break this up, first, we have an array of validation rules.

  zipCode: {
     identifier : 'zip_code',
        rules   : [
        {
          type   : 'empty',
          prompt : this.i18n.t('Please enter your zip code')
         }
      ]
   }

The first part zipcode is the identifier in Semantic.

The next bit of the identifier, this can match against either id, name or data-validate attributes on the element. We have here picked up the name which we’re using on our labels.

Next bit of the rules, which is an array of objects defining the type of validation, and the message to prompt the user with.

The second part is the settings:

inline : true,

delay : false,

on : 'blur',

This part says we want validation to occur on blur, delayed and to be inline. This gives us the following effect:

Fig. 2: Order Form after validation

To summarise the post, one can say we have seen here how the form to purchase the event ticket has been designed, coded and styled. The complete form can be seen on this link and the complete code can be seen here. The entire form has been designed in such a way to keep it simple, clear and trustworthy without losing the user interaction.

References:

Continue ReadingForms and their validation using Semantic UI in Open Event Frontend

Adding a Notification page using Ember.JS to Open Event Front-end

We have added a notification page for users, where they can have a look at their notifications and manage them separately. Here, we have two buttons for either viewing only the unread or all the notifications. The ‘mark all read’ button, as the name suggests will mark all the notifications as  read and is only present in `/notifications/`.

To create the notification page we have three steps

  • Create parent route for notification
  • Create sub routes for notification/all, notification/index
  • Design the notification page

We’ll be generating parents and sub routes by following three commands

ember generate route notifications
ember generate route notifications/index
ember generate route notifications/all
import Ember from ’ember’;

const { Route } = Ember;

export default Route.extend({
titleToken() {
return this.l10n.t(‘Unread’);
},
templateName: ‘notifications/all’,
model() {
return [{
title       : ‘New Session Proposal for event1 by  user1’,
description : ‘Title of proposal’,
createdAt   : new Date(),
isRead      : false
},
{
title       : ‘New Session Proposal for event3 by  user3’,
description : ‘Title of proposal’,
createdAt   : new Date(),
isRead      : false
},
{
title       : ‘New Session Proposal for event5 by  user5’,
description : ‘Title of proposal’,
createdAt   : new Date(),
isRead      : false
}];
}
});

In the js file we have defined a model, and this model is returned whenever the user navigates to this route ie /notifications.

We have used template name attribute to explicitly define template for this route. As /notifications/ and /notifications/all both have almost the same layout with different data, we have used the same template `notifications/all.hbs` for both of them.

{{#each model as |notification|}}

class=”ui segment {{unless notification.isRead ‘blue’}}”>
div class=”ui grid”>
div class=”row”>
div class=”eight wide column”>
h4 class=”ui header”>{{notification.title}}h4>
p>{{notification.description}}p>
div>
div class=”eight wide column right aligned”>
i class=”checkmark box icon”>i>
div>
div>
div class=”row”>
div class=”ten wide column”>
button class=”ui blue button”>{{t ‘View Session’}}button>
div>
div class=”six wide column right aligned”>
p>{{moment-from-now notification.createdAt}}p>
div>
div>
div>

{{/each}}

In the template we have checked if the notification is read or not and accordingly a blue segment is put.

<div class=“ui segment {{unless notification.isRead ‘blue’}}”>

Continue ReadingAdding a Notification page using Ember.JS to Open Event Front-end

Cross-Browser Issue: Dealing With an UI Problem Arising Due to Floating HTML Elements in Open Event Webapp

A few days back, I came across a rather interesting but hard to debug bug. The weird part was that it presented itself only on particular browsers like Firefox and didn’t exist on other browsers like Chrome.

In Open Event Webapp, we have collapsible session elements on track, room and schedule pages. The uncollapsed element would show you the major details like the title of the session, its type, name and a small thumbnail picture of the speaker. If the user clicks on it, then the element would collapse and more detail would pop up which would include the detailed description of the session and the speaker(s) presenting it.

Now, the problem which was occurring was that the collapsible sessions on the rooms page were behaving erratically. They were collapsing predictably but left behind a huge white space after they wound up on clicking. I have attached some screenshots to better demonstrate the problem. At first, I was confused. Because the same thing worked perfectly on Chrome.

collapsed.png

Collapsed State

uncollapsed.png

On Clicking Again

The actual solution for this problem turned out to be quite short (a one-liner in fact) but it took me a little while to solve it and actually understand what was going on. The solution:-

.room-filter {
 overflow: hidden;
}

Here, room-filter is the class applied to the session element.

Wait? But how did that solved the problem? Read on!!

As I mentioned in the title, the problem arises due to the floating HTML elements. I am just going to give a quick introduction to the float property. In case you want to read more about it, I have provided links at the end of the article which you can go through for a detailed explanation. Float is a CSS positioning property. It tells whether an element would shift to the right or left of its parent container or another floated element while other HTML elements like images, text and inline elements would wrap around it. One popular analogy which is often given is that of a textbook where the text wraps around the images. We can say that the image is floating to the left (or right) while the text wraps around it.

But how is this problem related to the floating elements still remain unclear? Hold on. This is the structure of the session div on the rooms page:

<div class="room-filter" id="{{session_id}}">

<div class="eventtime col-xs-2 col-sm-2 col-md-2">
<!-- Some Content -->
</div>

<div class="room-container">
<div class="left-border col-xs-10 col-sm-10 col-md-10">
<!-- Some Content -->
</div>
</div>

</div>

 

As we can see from the code, we have a session div with two divs inside it. We have applied bootstrap grid classes to them. These bootstrap layout classes actually make the elements float with a specified width (You can check it on the developer console). So, we have two floating div elements inside the parent div. Remember that although the floating elements remain the part of the document, they are taken outside of the normal flow of the page. Since the parent div here contain nothing but the floating elements, its height collapses to zero.

Because of this, Firefox was not able to correctly expand and collapse the session element because it’s actual height was not being computed and was set to zero. Now, if we apply any of the properties which can make the height of the parent element non-zero, we would be able to solve this problem. Chrome somehow managed to escape this issue and worked predictably.

To make the height non-zero, we apply this property:-

.room-filter {
   overflow: hidden;
}

An intuitive reason to explain why this fixes the problem is that when the element is in its default state (overflow: visible), it does not need to calculate its height to display properly. Once we set overflow: hidden, it needs to see whether the max-height or max-width has been surpassed and hence it needs to calculate its dimensions. Once the height is calculated, it is used in layout and the element no longer collapses.

correct.png

Problem solved.

Another alternative solution to solve the problem can be:

.room-filter {
   display: inline-block;
   width: 100%;
}

In case you want to read more about the float property, you can consult these links:

https://css-tricks.com/all-about-floats/

https://www.smashingmagazine.com/2009/10/the-mystery-of-css-float-property/

Continue ReadingCross-Browser Issue: Dealing With an UI Problem Arising Due to Floating HTML Elements in Open Event Webapp

Making Open Event Organizer Android App Reactive

FOSSASIA’s Open Event Organizer is an Android Application for Event Management. The core feature it provides is two way attendee check in, directly by searching name in the list of attendees or just by scanning a QR code from ticket. So as attendees of an event can be really large in number like 1000+ or more than that, it should not alter the performance of the App. Just imagine a big event with lot of attendees (lets say 1000+) and if check in feature of the app is slow what will be the mess at entrance where each attendee is waiting for his ticket to be scanned and verified. For example, a check in via QR code scan. A complete process is somewhat like this:

  1. QR scanner scans the ticket code and parse it into the ticket identifier string.
  2. Identifier string is parsed to get an attendee id from it.
  3. Using the attendee id, attendee is searched in the complete attendees list of the event.
  4. On match, attendee’s check in status is toggled by making required call to the server.
  5. On successful toggling the attendee is updated in database accordingly.
  6. And check in success message is shown on the screen.

From the above tasks 1st and 6th steps only are UI related. Remaining all are just background tasks which can be run on non-UI thread instead of carrying them on the same UI thread which is mainly responsible for all the user interaction with the app. ReactiveX, an API for asynchronous programming enables us to do this. Just for clarification asynchronous programming is not multithreading. It just means the tasks are independent and hence can be executed at same time. This will be another big topic to talk about. Here we have used ReactiveX just for running these tasks in background at the same time UI thread is running. Here is our code of barcode processing:

private void processBarcode(String barcode) {
  Observable.fromIterable(attendees)
      .filter(attendee -> attendee.getOrder() != null)
      .filter(attendee -> (attendee.getOrder().getIdentifier() + "-" + attendee.getId()).equals(barcode))
      .subscribeOn(Schedulers.computation())
      .observeOn(AndroidSchedulers.mainThread())
      .subscribe(attendee -> {
          // here we get the attendee and
          // further processing can be called here
          scanQRView.onScannedAttendee(attendee);
      });
  }

In the above code you will see the actual creation of an Observable. Observable class has a method fromIterable which takes list of items and create an Observable which emits these items. So hence we need to search the attendee in the attendees list we have already stored in database. Filter operator filters the items emitted using the function provided. Last two lines are important here which actually sets how our subscriber is going to work. You will need to apply this thread management setting to your observable while working on android. You don’t actually have to worry about it. Just remember subscribeOn sets the thread on which actually the background tasks will run and on item emission subscriber handle it on main thread which is set by observeOn method. Subscribe operator provides the function what actually we need to run on main thread after emitted item is caught. Once we find the attendee from barcode, network call is made to toggle check in status of the attendee. Here is the code of check in method:

public void toggleCheckIn() { eventRepository.toggleAttendeeCheckStatus(attendee.getEventId(), attendeeId)
      .subscribe(completed -> {
          ...
          String status = attendee.isCheckedIn() ? "Checked In" : "Checked Out";
          attendeeCheckInView.onSuccess(status);
      }, throwable -> {
          throwable.printStackTrace();
          ...
      });
}

In the above code toggleAttendeeCheckStatus method returns an Observable. As name suggests the Observable is to be observed and it emits signals (objects) which are caught by a Subscriber. So here observer is Subscriber. So in the above code toggleAttendeeCheckStatus is creating an Obseravable. Lets look into toggleAttendeeCheckStatus code:

public Observable<Attendee> toggleAttendeeCheckStatus(long eventId, long attendeeId) {
  return eventService.toggleAttendeeCheckStatus(eventId, attendeeId, getAuthorization())
      .map(attendee -> {
          ...
          // updating database logic
          ...
          return attendee;
      })
      .subscribeOn(Schedulers.io())
      .observeOn(AndroidSchedulers.mainThread());
}

We have used Retrofit+Okhttp for network calls. In the above code eventService.toggleAttendeeCheckStatus returns an Observable which emits updated Attendee object on server response. Here we have used Map operator provided by ReactiveX which applies function defined inside it on each item emitted by the observable and returns a new observable with these items. So here we have use it to make the related updates in the database. Now with ReactiveX support the complete check in process is:

(Tasks running in background in bold style)

  1. QR scanner scans the ticket code and parse it into the ticket identifier string.
  2. Using the identifier, attendee is searched in the complete attendees list of the event.
  3. On match, attendee’s check in status is toggled by making required call to the server.
  4. On successful toggling the attendee is updated in database accordingly.
  5. And check in success message is shown on the screen.

So now main thread runs only tasks related to the UI. And time consuming tasks are run in background and UI is updated on their completion accordingly. Hence check in process becomes smooth irrespective of size of the attendees. And app never crashes.

Continue ReadingMaking Open Event Organizer Android App Reactive

Choosing Semantic UI over Bootstrap for the Open Event Front-end

There are many design frameworks. In this blogpost, I am going to list out some pros of Semantic UI and why it is better suited for the Open Event project than Bootstrap or other frameworks.

Components:

The very main reason why we chose Semantic UI in Open Event frontend is the number of components it offers, such as step, segment, rails, cards, lists, headers, dimmers, dropdown, and form validation. We can use many of these components right away, which helps us to speed up development.

Installation:

Semantic UI also provides very good integrations with the majority of technologies available out there. Bootstrap, however, can be integrated anywhere with CDN’s.

Following are the technologies that Semantic UI can be integrated with:

  • As a NPM package
  • React
  • Angular
  • Ember JS

Also Semantic UI has CDN’s. Thus Semantic UI has easeful installation. The documentation on the official site provides a good view of installation.

Documentation:  

In regards to the documentation too, Semantic UI is more suitable for us. The official site has a neat and clean documentation for each component. In the case of Bootstrap, the documentation is also good but personally, for me, the Semantic UI’s documentation is easier to read understand.

Designed with completely em:

em is a unit in CSS which ensures that components are scaled according to the different device sizes.Every component is made by using em and rem so that the webpage doesn’t get distorted whenever screen size changes.

Concise and Expressive:  

In English, it’s much easier to say “There are three tall men” than “There is a tall man, a tall man, and a tall man”. This means that in Bootstrap, to achieve a thing (say a navbar), we need to have 2-3 nested classes of “navbar”, ”navbar-default”, etc. whereas with Semantic UI, it can be done with single one.

Code appearance:

In the case of Semantic UI, the code looks much cleaner since the classes created are of a short length and cause less confusion. Following code indicates how clean things can be done with Semantic UI.

class="ui secondary menu"> class="active item"> Home class="item"> Messages class="item"> Friends
class="right menu">
class="item">
class="ui icon input"> type="text" placeholder="Search..."> class="search link icon">
</div> <a class="ui item"> Logout </a> </div> </div>

                    Fig. Semantic UI

<nav class="navbar navbar-default">
class="container-fluid">
class="navbar-header"> class="navbar-brand" href="#">Brand
<!-- Collect the nav links, forms, and other content for toggling -->
class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
class="navbar-form navbar-left">
class="form-group"> type="text" class="form-control" placeholder="Search">
<button type="submit" class="btn btn-default">Submit</button> </form> <ul class="nav navbar-nav navbar-right"> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav>

                      Fig. Bootstrap

Looks:

In terms of looks, it is well said that “User makes user experience” i.e the user experience depends more on the user viewing the website rather than the developer. Still, according to me, every Bootstrap site looks similar whereas a site built with Semantic provides a different, crisp look. Unlike other sites, a site built with Semantic looks beautiful.

Redesigning infinitely:

Creating a site in Semantic means you never have to rewrite your codebase from scratch. Redesigning means retooling your UI toolkit, adjusting UI definitions, not creating entirely new HTML layouts.

Conclusion:

There are many reasons why Semantic UI is a bit more suitable, powerful than Bootstrap for the Open Event project. Still, the choice of the framework depends on the purpose of your website or what you want to build. The official documentation of Semantic-UI can be found out at https://semantic-ui.com.

Continue ReadingChoosing Semantic UI over Bootstrap for the Open Event Front-end

Connecting Social Apps with Open Event Orga API Server

Orga API Server serves the organizer with many features but there was need of one feature which will allow us to provide Organizer an option to connect with their social media audience directly from API server. This will also allow the Orga Server users to share their experience for different events on their social media platforms.

For this feature, some of the social media platforms added are:

  • FaceBook
  • Twitter
  • Instagram
  • Google+

    Before connecting with these social media platforms, we have to implement and test The Auth Tool – OAuth 2.0

Without going on introductory introduction to OAuth 2.0, Let’s focus on its implementation in Orga API Server

OAuth Roles

OAuth defines four roles:

  • Resource Owner
  • Client
  • Resource Server
  • Authorization Server

Let’s look at the responsibility of these roles when you connect your social apps with API server

> Resource Owner: User/Organizer ( You )

You as User or Organizer connection your accounts with API server are the resource owners who authorize API server to access your account. During authorization, you provide us access to read your account details like Name, Email, Profile photo, etc.

> Resource / Authorization Server: Social Apps

The resource server here is your social platforms/apps where you have your account registered. These Apps provide us limited access to fetch details of your account once you authorize our application to do so. They make sure the token we provide match with the authorization provided before through your account.

> Client: Orga API Server

Orga API Server acts as the client to access your account details. Before it may do so, it must be authorized by the user, and the authorization must be validated by the API.

The process to add

A simple work plan to follow:

  1. Understanding how OAuth is implemented.
  2. Test OAuth implementation on all 4 social medias.
  3. After Necessary correction. Make sure we have all views(routes) to connect these 4 social medias.
  4. Implementing the same feature on the template file.
  5. Make sure these connect buttons are shown only when Admin has registered its client credentials in Settings.
  6. Creating a view to unlink your social media account.

Understanding how OAuth is implemented.

Current Implementation of Oauth is very simple and interesting on API server. We have Oauth helper classes which provide all necessary endpoints and different methods to get the job done.

Test OAuth implementation on all 4 social medias.

Now we can work on testing on the callbacks of all 4 social apps. We have callback defined in views/util_routes.py For this, I picked up the auth OAuth URLs and called them directly on my browsers and testing their callback. Now on callback, those methods required some change to save user data on database thus connecting their accounts with API server. This lead to changes in update_user_details and on callback methods.

def update_user_details(first_name=None,
                        last_name=None,
                        facebook_link=None,
                        twitter_link=None,
                        file_url=None,
                        instagram=None,
                        google=None):

Make sure we have all views(routes) to connect these 4 social medias

This has to be done on views/users/profile.py Addition of one method

@profile.route('/google_connect/', methods=('GET', 'POST'))
def google_connect():
        ....
        ....
    return redirect(gp_auth_url)

and testing, correction on other 3 methods

Implementing the same feature on template file.

Updating gentelella/users/settings/pages/applications.html to add changes required to add this feature. This included ability to show URLs of connected accounts and functioning connect and disconnect button

Make sure these connect buttons are shown only when Admin has registered its client credentials in Settings.

    fb = get_settings()['fb_client_id'] != None and get_settings()['fb_client_secret'] != None
        ....
        ....
        ...

The addition of such snippet provides data to the template to decide whether to show those fields or not. It will not make any sense if there is no application created to connect those accounts by Admin.

Creating a view to unlink your social media account.

utils_routes.route('/unlink-social/<social>')
def unlink_social(social):
    if login.current_user is not None and login.current_user.is_authenticated:
        ...
        ...

A method is created to unlink the connected accounts so that users can anytime disconnect their accounts from API server.

Where to connect?

Settings > Applications

 

How it Works (GIF below )

Continue ReadingConnecting Social Apps with Open Event Orga API Server

Using FastAdapter in Open Event Organizer Android Project

RecyclerView is an important graphical UI component in any android application. Android provides RecyclerView.Adapter class which manages all the functionality of RecyclerView. I don’t know why but android people have kept this class in a very abstract form with only basic functionalities implemented by default. On the plus side it opens many doors for custom adapters with new functionalities for example, sticky headers, scroll indicator, drag and drop actions on items, multiview types items etc. A developer should be able to make an adapter of his need by extending RecyclerView.Adapter. There are many custom adapters developers have shared which comes with built in functionalities. FastAdapter is one of them which comes with all the good functionalities built in and also it is very easy to use. I just got to use this in the Open Event Organizer Android App of which the core feature is Attendees Check In. We have used FastAdapter library to show attendees list which needs many features which are absent in plane RecyclerView.Adapter. FastAdapter is built in such way that there are many different ways of using it on developer’s need. I have found a simplest way which I will be sharing here. The first part is extending the item model to inherit AbstractItem.

public class Attendee extends AbstractItem<Attendee, AttendeeViewHolder> {
  @PrimaryKey
  private long id;
  ...
  ...

  @Override
  public long getIdentifier() {
      return id;
  }

  @Override
  public int getType() {
      return 0;
  }

  @Override
  public int getLayoutRes() {
      return R.layout.attendee_layout;
  }

  @Override
  public AttendeeViewHolder getViewHolder(View view) {
      return new AttendeeViewHolder(DataBindingUtil.bind(view));
  }

  @Override
  public void bindView(AttendeeViewHolder holder, List<Object> list) {
      super.bindView(holder, list);
      holder.bindAttendee(this);
  }

  @Override
  public void unbindView(AttendeeViewHolder holder) {
      super.unbindView(holder);
      holder.unbindAttendee();
  }
}

The methods are pretty obvious by name. Implement these methods accordingly. You may notice that we have used Databinding here to bind data to views but it is not necessary. Also you will have to create your ViewHolder for adapter. You can either use RecyclerView.ViewHolder or you can just create a custom one by inheriting it as per your need. Once this part is over you are half done as most of the things are been taken care in model itself. Now we will be writing code for adapter and setting it to your RecyclerView.

FastItemAdapter<Attendee> fastItemAdapter = new FastItemAdapter<>();
fastItemAdapter.setHasStableIds(true);
...
// functionalities related code
...
recyclerView.setAdapter(fastItemAdapter);

Initialize FastItemAdapter which will be our main adapter handling all the direct functions related to the RecyclerView. Set up some boolean constants according to the project need. In our project we have Attendee model which has id as a primary field. FastItemAdapter can take advantage of distinct field of the model called as identifier . Hence it is set true as Attendee model has id field. But you should be careful about setting it to True as then you must have implemented getIdentifier in the model to return correct field which will be used as an identifier by our adapter. And the adapter is good to set to the RecyclerView.

Now we got to decide which functionalities we will be implementing to our RecyclerView. In our case we needed: 1. Search filter for attendees, 2. Sticky header for attendees groups arranged alphabetically and 3. On click listener for attendee item.

FastItemAdapter has ItemFilter adapter wrapped inside which manages all the filtering stuff. Filtering logic can be set using it.

fastItemAdapter.getItemFilter().withFilterPredicate(this::shallFilter);

Where shallFilter is method which takes attendee object and returns boolean whether to filter the item or not. And after this you can use FastItemAdapter’s filter method to filter the items. For sticky headers you need to implement StickyRecyclerHeadersAdapter extending AbstractAdapter. In this class you will have to implement your filter logic in getHeaderId method. This must return an unique id for items of the same group.

@Override
public long getHeaderId(int position) {
   IItem item = getItem(position);
   if(item instanceof Attendee && ((Attendee)item).getFirstName() != null)
       return ((Attendee) item).getFirstName().toUpperCase().charAt(0);
   return -1;
}

Like in this case we have grouped attendees alphabetically hence just returning initial character’s ASCII value will do good. You can modify this method according to your need. For other unimplemented methods just keep their default return values. With this you will also have to implement onCreateHeaderViewHolder and onBindHeaderViewHolder methods to bind view and data to the header layout. Once this is done you are ready to set sticky headers to your RecyclerView with following code:

stickyHeaderAdapter = new StickyHeaderAdapter();
final HeaderAdapter headerAdapter = new HeaderAdapter();
recyclerView.setAdapter(stickyHeaderAdapter.wrap((headerAdapter.wrap(fastItemAdapter))));

final StickyRecyclerHeadersDecoration decoration = new StickyRecyclerHeadersDecoration(stickyHeaderAdapter);
recyclerView.addItemDecoration(decoration);
adapterDataObserver = new RecyclerView.AdapterDataObserver() {
   @Override
   public void onChanged() {
       decoration.invalidateHeaders();
   }
};
stickyHeaderAdapter.registerAdapterDataObserver(adapterDataObserver);

For click listener, the code is similar to the RecyclerView.Adapter’s one.

fastItemAdapter.withOnClickListener(new FastAdapter.OnClickListener<Item>() {
  @Override
  public boolean onClick(View v, IAdapter<Item> adapter, Item item, int position) {
     // your on click logic
   return true;
  }
});

With this now you have successfully implemented FastItemAdapter to your RecyclerView. Although there are some important points to be taken care of. If you are using filter in your application then you will have to modify your updateItem logic. As when filter is applied to the adapter its items list is filtered. And if you are updating the item using its position from original list it then it will result in exception or updating the wrong item. So you will have to change the position to the one in filtered list. For example the updateAttendee method from Organizer App code looks like this:

public void updateAttendee(int position, Attendee attendee) {
   position = fastItemAdapter.getAdapterPosition(attendee);
   fastItemAdapter.getItemFilter().set(position, attendee);
}
Continue ReadingUsing FastAdapter in Open Event Organizer Android Project

Data Scraping with Selenium

There still exists websites without any APIs. Scraping data from such sites can be very time-consuming and manual. I created samples for Open Event App generator. One of the samples that I created was for All Hands Hawaii 2016. This site didn’t have any API to enable easy data scraping.

How do we find out if a website is using an API or not?

Using Google Chrome, go to View → Developer → Developer Tools. Under the Network →XHR look for API endpoint with a bit of Hit and Trial method. (XHR stands for XMLHttpRequest)

However, what if there is no API being used in the site? How would you scrape data in that case? Will you now manually click onto every hyperlink on the site and visit every page to get the data by manually copying and pasting it? Could there be someone doing that manual job for you? Or better could there be “something” doing that job for you? Yes, It’s selenium.

Selenium Web Browser Automation

Selenium is a tool that automates the task of browsing through the internet. Although, technically it is used for web testing purposes but there is no restriction to it’s utility.

Let’s get started with basics of Selenium:-

INSTALLATION:
  1. Run the following command pip install selenium (Quick Tip: It is advised to use virtualenv)
  2. Selenium requires drivers to run. Different browsers use different drivers. Choose an appropriate driver for your browser. some common drivers are shown below (Source)-

Chrome: https://sites.google.com/a/chromium.org/chromedriver/downloads

Firefox: https://github.com/mozilla/geckodriver/releases

Safari: https://webkit.org/blog/6900/webdriver-support-in-safari-10/

BASIC FUNCTIONALITIES-SELENIUM:

Visit a page ( using the get() ):

 driver.get(urlofpage)

Navigating to various elements on the visited/current webpage:

  1. BY ID: 
    WebElement element = driver.findElement(By.id(“ui_elementid”));
  2. BY CLASS NAME:
    List<WebElement> cheeses = driver.findElements(By.className(“cheese”));
  3. BY TAG NAME:
    WebElement tag = driver.findElement(By.tagName(“tag_name”));
  4. BY CSS: WebElement cs = driver.findElement(By.cssSelector(“#”));
  5. BY LINK TEXT:
    WebElement cheese = driver.findElement(By.linkText(“blog”));

    If the element href is something like urlofpage?q=blog.

  6. BY XPATH:
  7.  List<WebElement> xp = driver.findElements(By.xpath(“//input”))

 

We can also use JavaScript along with Selenium. This might be a helpful thread for the same.

Another really good link for the same is http://www.marinamele.com/selenium-tutorial-web-scraping-with-selenium-and-python

Continue ReadingData Scraping with Selenium

Testing User Interactions with Espresso

Espresso is a testing framework which provides the facility to write the tests for user interactions and unitary tests. Since the release of its version 2 it is now a part of Android Testing Support Library.

The android apps we build at FOSSASIA follow rigorous testing methods. See this simple UI test  in the Phimp.me app using espresso to check if button and bottom navigation are displayed in an activity. You can also find our other tests related to API and databases in the Open Event Android App.

In this blog we learn how to add this facility to your app and write a test for a simple app that takes the name of from the user and prints it on the other screen on button click.

Adding espresso support

  • Install android support repository if not already present. You do it by following Tools -> Android -> SDK Manager
Tools you need to download for testing
  • Add the following dependencies to your app’s build.gradle file
dependencies {
    androidTestCompile 'com.android.support.test:runner:0.5'
    androidTestCompile 'com.android.support.test:rules:0.5'
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'

}
  • Specify the test instrumentation runner in default config
android {

    defaultConfig {

        // ....

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }

}

Before we begin with writing our tests knowing some basic components will help in understanding the code better. Writing tests with espresso is easy as its construction is similar to English language.

The three major components are 

  • ViewActions        : Allows you to interact with views
  • ViewAssertions   : Allows you to assert the state of a view.
  • ViewMatchers     : Allows you to locate a view in the current view hierarchy.

Suppose we want to test if text is displayed in the view, we can do it by

onView(withId(R.id.textView))                              //ViewMatcher

 .perform(click())                                         //ViewAction

 .check(matches(isDisplayed()));                           //ViewAssertion

Example

Consider an app which takes a name from the user and displays it on the next screen on clicking the button.

To perform this kind of test we will write

//Locate the view with id "name" and type the text "Natalie"

onView(withId(R.id.name)).perform(typeText("Natalie"));

//Locate the view with id "next" and click on it

onView(withId(R.id.next)).perform(click());

//Locate the view with id "new_name" and check its text is equal with "Natalie"

onView(withId(R.id.new_name)).check(matches(withText("Natalie")));

You can run tests by right clicking on the class and selecting the “run test” option. If the interaction is not as expected then the message will be displayed.

Up until now unit test were in main focus but as we move towards the more complex apps where user interaction plays an essential role, UI testing becomes equally necessary.

References:

Continue ReadingTesting User Interactions with Espresso