All Posts in The Programming Mechanism

May 25, 2018 - Comments Off on Singing the General Data Protection Regulation (GDPR) Blues

Singing the General Data Protection Regulation (GDPR) Blues

Everyone's been inundated with emails from websites you subscribe to this week. We decided to do a little research about GDPR and managed to find a few things that are worth exploring and noting when modifying your individual privacy statements. For more GDPR guidance and options visit Delphix.

We’ve reviewed how the VDR market and other companies have revised their Privacy Policies and have found a few notable changes that would be worth discussing. The Mechanism also suggests that you reach out to your internal legal teams to revise your Privacy Policy to address the EU’s new General Data Protection (GDPR). Then when you are struggling with GDPR you should give Teamwork a call as they are brilliant with that.

A reminder that The Mechanism LLC is not a legal firm or legal entity and our brief research into this subject is intended to help you begin your conversations with your internal legal representatives. Your "legal-eagles" will have significantly more useful and appropriate information as legal experts than we could ever provide. We make no legal assurances for any information supplied, as we have performed research as you or your team would online, and have attempted to supply our findings as a service to you.

According to experts like web design Hamilton, three notable alterations we’ve identified with regard to GDPR changes in some of the websites we visit (achieved through downloading and directly comparing pre-May 25th privacy policies vs. post-May 25th, 2018) are related to:

Legal basis for processing Personal Data

We found this paragraph on a website we frequent added post May 25th, 2018. Note that the change outlined below from pre-May 25th vs post-May 25th:

pre-May 25th, 2018

We use the information we collect about you to:
Establish your account and provide the Services;
Fulfill your requests and provide customized content to you;
Communicate with you through email, notices posted on the website, and other means available through the Services.
Create, tailor, deliver and study the effectiveness of advertising and promotional material both on and off of the Services, as well as for analytics (including as described in the Online Analytics, Advertising and Do-Not-Track section below);
Improve the Services and to research and develop innovative features and new services;
Provide feedback to third party businesses that are listed on the Services; and
Investigate, prevent, or take action regarding unlawful or harmful activities, including potential threats to the physical safety of a person, potential fraud, and violations of our Terms of Service that can be punished.
Please note that we may anonymize and/or de-identify information collected through the Services or via other means so that the information no longer relates to you. Where we have appropriately anonymized and/or de-identified information so that it no longer identifies you personally, our use and disclosure of such information is not subject to this Privacy Policy, and may be used and disclosed to others without restriction.

Revised post-May 25th, 2018 (note new copy added in front of the content above)

What legal basis do we rely on to process your Personal data?
Consent - When you receive our promotional material, you consent that your Personal data will be processed by us and we rely on this consent. You have the right to withdraw consent at any time. We will stop to process data after consent is withdrawn, where consent is the only legal basis for processing.
When you fulfill a contract – We will process your Personal data when you take steps to enter into a contract with us such as sign up for a free trial, use or purchase our service or products and for the performance of contract that you have entered with us.
Legitimate Interest – We process your data when it is in our legitimate interests to do this and when these interests are not overridden by your data protection rights.
Legal obligation - We may process your Personal data to comply with our legal and regulatory obligations such as preventing, investigating and detecting crime, fraud or anti-social behavior and prosecuting offenders, including working with law enforcement agencies. Your data may be processed in order to satisfy the applicable law or enforceable governmental request, learn more by getting a consultation with the Steven Feakes & Associates firm.

We use the information we collect about you to:
Establish your account and provide the Services;
Fulfill your requests and provide customized content to you;
Communicate with you through email, notices posted on the website, and other means available through the Services.
Create, tailor, deliver and study the effectiveness of advertising and promotional material both on and off of the Services, as well as for analytics (including as described in the Online Analytics, Advertising and Do-Not-Track section below);
Improve the Services and to research and develop innovative features and new services;
Provide feedback to third party businesses that are listed on the Services; and
Investigate, prevent, or take action regarding unlawful or harmful activities, including potential threats to the physical safety of a person, potential fraud, and violations of our Terms of Service.
Please note that we may anonymize and/or de-identify information collected through the Services or via other means so that the information no longer relates to you. Where we have appropriately anonymized and/or de-identified information so that it no longer identifies you personally, our use and disclosure of such information is not subject to this Privacy Policy, and may be used and disclosed to others without restriction.

Retention of Data

We found this paragraph altered (on a website we frequent) post-May 25th, 2018:

pre-May 25th, 2018

We keep your information for as long as your account is active or as needed. For example, we may keep certain information even after you close your account if it is necessary to comply with our legal obligations, meet regulatory requirements, resolve disputes, prevent fraud and abuse, enforce our agreements or as part of our Website data backup process. We may keep your data in a published or unpublished format on the Services or in backups of the Website.

post-May 25th, 2018

Data Retention
We retain your information as long as your account is active or as needed to provide you services or because we have an ongoing legitimate business need to do so. We also retain and use your information as necessary to comply with our legal obligations, resolve disputes and enforce our agreements. We store your information as long as is necessary for the purpose for which we have collected it. When we have no ongoing legitimate business need to process your personal information, we will either delete or anonymise it or, if it is possible (e.g. your personal information is stored for backup archives) then will securely store your personal information and isolate if from any further processing until the deletion/erasure is possible.

Rights identified with regard to your internal Data Controllers

We found this content added (to a website we frequent) post-May 25th, 2018:

Your Rights within the EU
Whenever you use our services from within the EU the following rights apply to your user account:
The right to be informed, The right of access, The right to rectification, The right to erasure, The right to restrict processing, The right to data portability, The right to object and rights in relation to automated decision making and profiling.
If you wish to exercise any of the above rights, please contact us using the contact details set out below. For the protection of your privacy and security, our Data protection team shall take every reasonable step to ensure that your identity is verified before granting access, or rectification, or deletion.
Note the Controller of data
If you live in the EU, the Controller of your data is (your company) with its principal place of business at (address).

Also, please note the following links we found that may also be helpful:

And finally, in the spirit of all the legal-eagles* out there, here's our own for you to ponder as you complete this post:
*This information is being provided as a suggestion from The Mechanism to initiate a conversation with your internal or external legal team, and not as a prescriptive solution to modifying your individual Privacy Policies. Your use of the information contained within this document signifies your complete understanding and compliance with this statement.

For women is very important to show off a nice makeup. You can get a smooth makeup with advises from makeup professionals.

Good luck with your own Privacy Statements and your research. The mighty Internet continually evovles to protect It's users, and for that we applaud It.

Published by: davefletcher in The Programming Mechanism, The Reading Mechanism
Tags: , ,

October 17, 2014 - Comments Off on A Brief Description of the SPF record

A Brief Description of the SPF record

A client recently came to us with problems receiving emailed form submissions from their website. We did a little testing and realized that indeed the emails were being sent by the server but something was stopping them during transit. In our research, we had to dig deeper into SPF records.

An SPF (Sender Policy Framework) record, validates an IP address as permitted to send emails from that Domain. Once propagated, the DNS record serves as a list of verified senders, which the recipient of an email can use to check against. If you need help with this process, services like IT support Chicago can work in your business network.

The SPF record was introduced because the ubiquitous SMTP (Simple Mail Transfer Protocol) allows a computer to send email claiming to be from any domain. Spam and phishing emailers use this to send email purporting to be from a trusted source.

With an SPF record, a receivers spam filter is more likely to accept the message as it is coming from a validated source. It also discourages potential spammers from using your domain as a sending address, knowing that domains with SPF records are more likely to be rejected by recipient spam filters, if the senders IP does not match one associated with the record.

Once an SPF record is created, it is important to ensure that all computers that will be sending emails are included, as the presence of the record indicates that any email not declared is dubious. This is the problem we ran into, where an SPF record was added to the DNS zone, but did not include the server hosting the website in it’s list of IP addresses.

Here is an example SPF TXT record:

example.com TXT “v=spf1 ip4:192.0.2.0/24 ip4:198.51.100.123 a ~all”

Published by: georgebrassey in The Programming Mechanism
Tags:

August 19, 2014 - Comments Off on Could the iWatch Revolutionize Medical Research?

Could the iWatch Revolutionize Medical Research?

“Talkback Tuesdays” is an original weekly installment administered by hcp event planning ltd., where a team member of The Mechanism is asked one question pertaining to digital design, inspiration, and experience. The Q&A will be featured here on The Mechanism Blog as well as on The Mechanism’s Facebook, Twitter, and Instagram, every Tuesday. Feel free to offer up your 2¢ in the comments.

George Brassey, The Mechanism’s lead developer, discusses the great potential smart watches can have in revolutionizing medical research and healthcare management. It seems like only a matter of time!

What new piece of tech are you most excited about hitting shelves?

I'm excited to see what sensors Apple will introduce with the iWatch. I'm hoping they announce a watch with an array of sensors which might revolutionize health care research. Last year there was a huge amount of media buzz around the wearable space, with nothing appearing. This year the rumor mill is turning again and it sounds like Apple will finally announce an iWatch next month to be released later this year/early next year. Why am I interested? Last year I didn't like the idea of the wearable. The potential uses didn't interest me. I already have a phone, tablet and laptop. I don't need yet another screen. Especially considering how limited the functionality will be on such a small device. This year, however, I've been hearing about the sensors that will be included.

I'm a migraine sufferer. From time to time, without warning, I get massive blind spots in my field of vision, followed by debilitating headaches. Research on migraines has been inconclusive. The Mayo Clinic lists: hormones, foods, food additives, drinks, stress, sensory stimuli, changes in wake-sleep pattern, physical factors, changes in the environment, and medications; as potential causes. That's a long list with very little practical information as to how to prevent a migraine. I will be interested to see what could be learned by analyzing various health markers preceding migraines.

Depending on how Apple's new Healthkit SDK deals with privacy, the platform could standardize the sharing of medical records. Currently, there is very little access to medical data for researchers. Fears of records getting into the wrong hands means that acquiring data for research often requires a new study, even if a similar study has been done before. This involves, raising money, finding volunteers and conducting the study which may take months, even years. Most health information is under lock and key. The proliferation of devices to passively record a wealth of data could provide easy access for life saving research.

August 15, 2014 - Comments Off on How to Build an Easy Embedabble Widget

How to Build an Easy Embedabble Widget

Building with iframes is a fantastic way to create seamless, easy to implement, embeddable widgets. Once set up, creating multiple instances linking to your service is easy to do. Existing within a website, an iframe is like a window onto another website. Rather than forcing open another window, a user can interact with another service within the context of the website they have navigated to.

Over here at The Mechanism, we have been using iframes to integrate our custom bug tracking solution with client websites during user assisted testing. We needed an inconspicuous tool which would allow clients to seamlessly review work and submit bugs as they find them.

The requirements for this front end bug catcher:

  1. Simple to embed and easy to implement across many projects
  2. Sandboxed so that it doesn't cause any conflicts with the project DOM, JS or CSS
  3. Simple architecture which works on all browsers
  4. Responsive; it must work on all device sizes and form factors
  5. Context Aware; diagnostic information will require knowledge of the parent document (the website under bug tracking )

Our first iteration of the bug tracking widget violated the second requirement. For our first prototype, we loaded a script and pulled in our view and styling files through JSONP (a method for circumventing Same-Origin Policy, you can read about it here). This worked in our limited prototype but caused a few issues. First of all, we had to give our DOM elements verbose ID's and class names to ensure there would no conflict with the parent document. Secondly, we ran the risk of causing script conflicts with our dependencies. We used a script loader to minimize this risk, however we could never be sure. Finally, we were at the mercy of the stylesheets loaded by the parent which required us to write additional resets to ensure consistent appearance across projects. However, repairs like this are equivalent to bailing a sinking ship rather than repairing the leak.

So for our second iteration we converted the widget into an iframe. To do so we still had to find a way to get around the Same-Origin Policy. The Same-Origin Policy restricts communication between two documents; the parent window and the iframe. Cross Document Messaging is a new addition to the HTML5 specification, which allows for simple string communication between documents. This is supported by most modern browsers, however, there are many hacks necessary for older browsers.

easyXDM

easyXDM is a great library built to cross this great divide introduced by iframes. It uses the HTML5 postMessage() method when available and uses many fallbacks when necessary, ensuring the free flow of information between documents. For the developer, it exposes two protocols for data transfer. The first is a socket, which will send a string between the documents. This method requires us to parse and decipher the string before performing the relevant action on that information. The second option is an RPC (Remote Procedure Call), specifically JSON-RPC. JSON-RPC is a specification for calling functions from remote software, and for data to be returned. This allows for a much more dynamic interaction between our two documents where each process exists in their relative scope and can communicate as discreet functions would be expected. For our needs, the simpler option and the one we will be employing is the RPC protocol.

To implement easyXDM we must load our dependency and create an RPC instance, with the necessary proxy objects and method stubs. We will initiate this within a script loaded on the parent document. This script will embed our iframe and act as our gateway to the bug tracking widget.

On our parent document we will place an asynchronous script call to our remote script

 

// footer.html

 

In our script we will start by loading our easyXDM dependency

 

// main.js

var serverURL = 'http://www.example.com/our-remote-service/',

iframeFile = 'iframe.html',

depends = {

'easyXDM': serverURL + 'js/easyXDM.min.js'

};

Object.size = function(obj) {

var size = 0, key;

for (key in obj) {

if (obj.hasOwnProperty(key)) size++;

}

return size;

}

var scriptCount = Object.size(depends); // count of scripts required

var scriptLoads = 0; // count of script loaded

for (var key in depends) {

if (depends.hasOwnProperty(key)) {

loadScript(key, depends[key], function() {

scriptLoads++;

if (scriptLoads === scriptCount) {

main();

}

});

}

}

function loadScript (dependency, src, callback) {

// this function checks if the dependency is present.

// it waits for load before executing the callback.

if (window[dependency] === undefined) { // if dependency is not present

var scriptTag = document.createElement('script');

scriptTag.setAttribute('type', 'text/javascript');

scriptTag.setAttribute('src', src);

if (scriptTag.readyState) {

scriptTag.onreadystatechange = function () { // For old versions of IE

if (this.readyState == 'complete' || this.readyState == 'loaded') {

callback();

}

};

} else { // Other browsers

scriptTag.onload = callback;

}

(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(scriptTag);

} else {

callback();

}

}

 

  1. Lines 1-5 we are declaring a some variables that will be used later.
  2. Lines 7-16 we extend the Object object with a method which will return the length of our depends array on line 15, along with a variable to hold an index value.
  3. Lines 18-27, we run a loop through the depends array and call a function loadScript(), which takes the name of our dependency, the url it can be found at and a callback which will be run once the dependency is loaded.
  4. Lines 29-49, our function which will test the presence of the dependency and load the script if it is not found. It uses various methods to ensure the script is loaded before running the callback function.

Next we will create our RPC instance which will load the iframe

 

// main.js

.

.

.

var iframeContainer = document.createElement('div');

iframeContainer.style.position = 'fixed';

iframeContainer.style.zIndex = 999;

iframeContainer.style.bottom = 0;

iframeContainer.style.left = 0;

iframeContainer.style.top = "auto";

iframeContainer.style.right = "auto";

iframeContainer.style['max-height'] = '100%';

iframeContainer.style['max-width'] = '100%';

document.getElementsByTagName('body')[0].appendChild(iframeContainer);

var rpc = new easyXDM.Rpc({

remote: serverURL + iframeFile,

container: iframeContainer,

props: {

id: 'bug-iframe',

frameborder: '0',

scrolling: 'no',

marginwidth: '0',

marginheight: '0',

allowTransparency: 'true',

style: {

height: '100%',

width: '100%',

display: 'block'

}

}

},

{

local: {

resizeiFrame: function (widthReq, heightReq, allowScroll) {

var windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,

windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

var width = (widthReq < windowWidth) ? widthReq : windowWidth;

var height = (heightReq < windowHeight) ? heightReq : windowHeight;

iframeContainer.style.width = width + 'px';

iframeContainer.style.height = height + 'px';

var sc = (allowScroll) ? 'yes' : 'no';

document.getElementById('mech-bug-iframe').scrolling = sc;

return {

x: width,

y: height

};

},

parentInfo: function () {

return {

width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,

height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight,

url: window.location.href

};

}

}

});

 

  1. Lines 5-16; we are creating the iframes container with properties for it's layout within the parent documents DOM
  2. Lines 18-34; our RPC instance with the address to find the iframe contents, a container to place the div in, and some properties to control it's appearance
  3. Lines 34-64; is where we declare the methods we will be exposing to our iframe. resizeiFrame() and parentInfo() will allow us the adjust the size of the iframe and return diagnostic information respectively. They will be called from within our iframe

In our iframes markup we will load easyXDM and a shiv for older browsers without support for JSON, plus another .js file where we will instatiate our RPC connection.

 

 

In our iframe-main.js file, we will create another instance of easyXDM.Rpc and create stubs for our remote methods

 

// iframe-main.js

var rpc = new easyXDM.Rpc({},

{

remote: {

resizeiFrame: {},

parentInfo: {}

}

});

.

.

.

rpc.parentInfo(function(parentInfo) {

var diagObject = {

'width' = parentInfo.width,

'height' = parentInfo.height,

'url' = parentInfo.url

}

});

 

  1. Lines 2-8; we create our rpc object with the relevant stubs, referring to the remote methods
  2. Lines 14-20; an example of how we call our remote function. Notice the anonymous function we pass to the remote function to return our requested data. This is an asynchronous function

Stay tuned for more on the Venus project to find out where it goes next. Dhruv Mehrotra will be back in a few weeks with a blog post going over some of the steps taken to set up the Ruby on Rails server behind Venus. And we will have meetup at our offices the second week of September. Hope to see you there!

Published by: georgebrassey in The Programming Mechanism
Tags: , , , ,

June 20, 2014 - Comments Off on Building The BugTrap JavaScript Widget

Building The BugTrap JavaScript Widget

Over here at The Mechanism's headquarters, Team Mechanism has been busy working on a better way to track bugs, code named: project:Venus. We want to make it easier for our clients to report bugs while reviewing projects and improve our workflow by allowing internal communication on a bug by bug basis.

The idea came to us as while working on another project. We realized we had the technology to build a swift prototype by leveraging tools that were already part of our arsenal. More on this in later posts. For now, we will focus on the front end javascript widget, "The Bug Trapper" if you will.

As an agency, we often have many projects in process so our bug tracker needs to be easy to implement across multiple projects and domains: we wanted to use a simple script tag which would be added to projects during test phases, with the project id included in the script 'src' GET parameters.

This posed a couple problems:

  1. Scripts are not aware of the GET parameters from their requests
  2. AJAX requests cannot load anything other than scripts from other domains

 

1. Javascript and Parameters Passed through GET Requests

We came across this tip for pulling the parameters from the script request. It actually has little to do with a GET request as the parameters are parsed by the script on the client side. By providing the name of the script, it searches the DOM for itself (javascript has no awareness of how it has been called or where it exists in the DOM). And then we do some regex magic to construct an object of key/value pairs. We have abstracted the code slightly from the original. Below is our script:

 

// Extract "GET" parameters from a JS include querystring

function getScriptTag(script_name) {

// Find all script tags

var scripts = document.getElementsByTagName("script");

// Look through them trying to find ourselves

for(var i=0; i<scripts.length; i++) {

if(scripts[i].src.indexOf("/" + script_name) > -1) {

return scripts[i]

}

}

// No scripts match

return {};

}

function getParams(script_tag) {

// Get an array of key=value strings of params

var pa = script_tag.src.split("?").pop().split("&");

// Split each key=value into array, the construct js object

var p = {};

for(var j=0; j <pa.length; j++) {

var kv = pa[j].split("=");

p[kv[0]] = kv[1];

}

return p;

}

 

 

2. Cross Domain AJAX Requests

For security purposes, AJAX requests only accept scripts from other domains. This is a problem for our widget which we'd like to build modularly, separating the script logic, markup and styling into separate files, while maintaing the simplicity of including a single script when creating new instances.

There is a work around and it involves turning the response from our server into JSONP. JSONP is JSON with Padding. Essentially our server response is turned into a JSON object and then gets wrapped in a function, which will get called on the client side and return an object containing our data.

Thank the heavens for jQuery. jQuery's AJAX/getJSON method has baked in support for JSONP which will expect the callback function name to be a random string (an added layer of security), and will process the data, provided it gets the correct response from the server. On the client side, all we need to do is indicate we will be expecting the response to contain a callback function by adding "?callback=?" to our URL.

 

var stylesheetURL = "http://example.com/getmystylehsheet?callback=?";

$.getJSON(requestURL, function(data) {

$('head').append('

');

}

 

On our rails server we route this request by wrapping the intended response in a function, the name of which is passed by jQuery as a parameter through the request. Below is the ruby on rails controller code to do this on our server:

 

def getmystylesheet

css = File.read("path/to/stylesheet.css").to_s

json = {"css" => css}.to_json

callback = params[:callback]

jsonp = callback + "(" + json + ")"

render :text => jsonp, :content_type => "text/javascript"

end

 

We're beginning a test cycle with the bug tracker on some internal projects and we will be rolling this out on upcoming client work. Hopefully, with feedback from our clients, we will continue this project with a view to scaling it. Stay tuned for future updates!

Published by: georgebrassey in The Programming Mechanism
Tags: , , , ,

May 30, 2014 - Comments Off on Configuring Sunspot Solr Search Controller

Configuring Sunspot Solr Search Controller

Search is the compass of the internet. It guides us to the content that we are really looking for and helps avoid the stuff we don’t really care about. Or at least that’s how it is supposed to work. It turns out that beyond just the complexity of installing and configuring a search server, it can also be difficult to account for the various use cases of your search tool. Lets take a quick look at how The Mechanism engineers were able to tackle this challenge when building a restaurant search application for SafeFARE.

The good folks at foodallergy.org enlisted our services to build a restaurant search sushi near me that will allow users to find allergy-aware restaurants based on any combination of 9 criteria. Using the Ruby on Rails framework and Sunspot Solr (a Ruby DSL for the Lucene Apache Solr search server) we built this search app, and learned a few things on the way.

If a user searches for restaurants in a ZIP code should we only return restaurants within that ZIP code, or should we include restaurants from other nearby ZIP codes in our search results? And if we include other ZIP codes, how many other ZIP codes? How should we order the results? These and other similar questions helped up to come up with the structure of our search controller.

Figure 1.1

if params[:search].present?

@search = Restaurant.solr_search do

fulltext params[:restaurant_name] # runs a full text search of

with(:approved, :true) #facets approved restaurants

if params[:cuisine_search].present? #user also entered cuisine preference

any_of do

params[:cuisine_search].each do |tag|

with(:cuisines_name, tag) # facet by matching cuisines

end

end

end

if params[:address].present? || params[:city_search].present? || params[:state_search].present? || params[:zip_search].present?

#if any location fields are present, geocode that location

with(:location).in_radius(*Geocoder.coordinates(whereat), howfar)

#facet based on user given location,

end

order_by_geodist(:location,request.location.latitude,request.location.longitude)

@restaurants = @search.results

end

 

It took us about a week but we were finally able to come up with enough if statements to cover every one of the 362,880 possible combinations of search queries. Figure 1.1 is a small sampling of how we implement search when a user types in a restaurant name, cuisine preference, and restaurant location. First we search the solr index for whatever the user enters in the restaurant_name field, then cut that list down to only the approved restaurants, then we check to see if the user also entered a cuisine preference, if so we facet our list down to restaurants that match that cuisine, if the user did not enter a cuisine, we skip that step, then we check if the user entered a location that they would like to search like a city, or state, and we facet our list down to only restaurant’s in that area. Using this strategy we can create sort of a Venn diagram that allows us to drill down only to the information that we want, and point that result to the restaurant variable. To increase the functionality of the site, The Mechanism engineers implemented an IP lookup to automatically detect the IP address and location of the user, and order search results by how close the restaurant is to the user.

A second major challenge that many developers face when using a search server is deployment. In order to use solr in a production environment, you will need a Java app servlet like Tomcat or Jetty, and you will need an instance of Apache Solr. Developers may consider installing standalone versions of Tomcat and Solr Sunspot depending on their hardware capabilities, but sunspot comes bundled with a Jetty server which can be used in production by running the command RAILS_ENV=production rake sunspot:solr:start

And voila! we have implemented an advanced search tool that will help users find allergy-aware restaurants all across the nation and may even save somebody’s life one day.

Published by: Sharon Terry in The Programming Mechanism
Tags: , ,

May 16, 2014 - Comments Off on What We Talk About When We Talk About Testing

What We Talk About When We Talk About Testing

Until recently I considered writing tests for my applications much like reading Dickens in high school: boring, repetitive, hard to understand, and yet for some reason a total necessity.  What's more, I wrote tests about as frequently as I read Dickens - and I've never read any Dickens.  My meandering point here is that Test Driven Development (TDD) seems to be the standard of the rails community, yet I don't know a single person who actually does it.  With that it mind, I decided to develop our last client's application with tests written to the best of my ability.  At first I thought I was burying my productivity in the minutia of each test, but I ended up learning quite a few things, including the value of testing.

Tools

I guess the first thing to do here is to describe my tools.  To test with Rails I used RSPEC, Factory Girl, and Capybara.

RSpec is a testing tool for Ruby.  Baked into the gem is a rich command line program with detailed error reporting. The beauty of Ruby, and RSpec, is that it enables you to write human readable tests that tell a story. For instance:

it 'has a list of employees' do

employee = Employee.new('John', 'Smith')

company = Company.new([student])

expect(company.employees).to include(student)

end

 

Though testing with RSPEC ensures that our models behave the way we expect, there is a serious problem with this approach: It takes forever. Testing any sort of interesting behavior not only involves extensive amounts of setup to your environment, but a tremendous amount of code to create various instances of your model. This is where Factory Girl comes in.  Factory Girl allows a tester to create factories that create multiple records for a model with some generic attributes that are able to be overridden as needed.  This means that creating a unique record is as simple as:

FactoryGirl.create(:employee, name: "Jon Snow").

My last tool in my little testing toolkit is Capybara. Where RSpec is a way to test your models, Capybara allows your application to test external behavior. In other words Capybara provides a simple way to test user stories and general behavior. Heres an example:

'When I sign in' do

visit user_sign_up_path

fill_in 'Login', :with => 'DavidBowie@spidersfrommars.net'

fill_in 'Password', :with => 'whereWereTheSpiders?'

click_link 'Sign in'

end

 

 

So What's The Point

When I started, I assumed that testing would help to prevent bugs. While this is likely the case, I found that using TDD did something far more valuable. By letting tests to drive the code, developers are forced to conceptualize their application before a single semi-colon is ever written. This forces developers to step through their own logic, which in my case, is full of inconsistencies and little things that I had not thought through fully...likely because I have never read Dickens.

Published by: dhruvmehrotra in The Programming Mechanism
Tags: , , ,

May 8, 2014 - Comments Off on An Event Apart • Boston • 2014

An Event Apart • Boston • 2014

Here are some thoughts on talks at the recent An Event Apart, in Boston.

Understanding Web Design - Jeffrey Zeldman

  • Web Design is held to the expectations of other media. Often ignoring the intrinsic strengths of web
  • Like typography, web design's primary focus is communicating content
  • Technology is often a hangup for people, when the user and their needs should be the primary focus of designers. "Design for people, not browsers!"
  • Design is about detail
  • A great website will subtly guide the user to their desired destination

Designing Using Data - Sarah Parmenter

  • Design is no longer a differentiator. Making things look nice is common. The differentiator today is designing with purpose — answer the question 'why?'
  • When the right metrics are studied, data offers objective and actionable feedback
  • Data should allow a team to unite behind an objective goal — such as: Increase clicks etc.
  • Customer facing advertising is most effective when honest and transparent
  • Iterative design allows you to be flexible and try new things

Responsive Design is Still Hard/Easy! Be Afraid/Don't Worry! - Dan Mall

  • Frameworks rather than processes, mean you define a set of constraints within which a project exists, and within this you find out what you can do that's unexpected
  • Be active within your framework and volunteer/get involved with stages of production outside of your discipline
  • Each member of a team will have divergent perspectives at the start of each project cycle, they should become convergent by the end. These are focal points
  • Rinse and repeat the cycle, getting smaller each time to increase team involvement
  • Extensive preparation should make the assembly part of the process the shortest

Screen Time - Luke Wroblewski

  • Mobile is the dominant web browser worldwide
  • Responsive design includes additional considerations than just screen size (multiple input types, variable ambient lighting etc)
  • Screen size is a poor proxy for many of these considerations (screen size does not reveal input type)
  • A user's posture or distance from device will also affect it's design, independent of screen size or number of pixels
  • Design for human proportions, not pixels.

Content/Communication - Kristina Halvorson

5 key points for working with a client:

  • Principles: these are internal motivators based on our better intentions. They can unify a team
  • Strategy: pinpoint your goals and provide helpful constraints with which to execute
  • Process: the process is not God, it should change and grow as needs change. Regular post mortems are encouraged
  • Roles: RACI key for each agent on the client end. Responsible. Accountable. Consulted. Informed
  • Perceptions: Translate to facilitate communication between different disciplines

UX Strategy Means Business - Jared Spool

  • Design is the rendering of intent. Both user and provider
  • Content delivery is as important as the content itself and vice versa. Great UX cannot exist without great content
  • Advertising is unhelpful for all parties involved
  • Strategic priorities in business can inform design considerations (increase revenue, reduce cost etc)
  • There are a variety of models for monetizing the web

The Long Web - Jeremy Keith

  • HTML allows for fantastic accessibility, deprecation and backward compatibility
  • New HTML specifications can be adopted early as they will be skipped over when unsupported
  • Progressive enhancement means you start with the lowest common denominator and then enhance as much as you like
  • Progressive enhancement protects the experience from unaccountable errors such as unrelated javascript errors
  • Text formats will last longer than binaries. Binaries are forever changing and becoming outdated

Responsive Design Performance Budget - Paul Irish

  • Mobile users expect their content to load faster than the desktop
  • Web growing is latency limited. The nature of requesting many small files means that a user's experience is improved by reducing the number requests
  • UX can be greatly enhanced by prioritizing critical data and rendering early on
  • Separate the critical CSS from non-critical. Load non-critical at the end of the page. Aim for main content to load in 1 sec (< 14kb)
  • The number of higher latency users is increasing

The Chroma Zone: Engineering Color on the Web - Lea Verou

  • Colors in web browsers have many nuances and limitations
  • Hex and RGB are poor representations for human reading
  • HSL and HSLa are better although they are not perceptually uniform (we perceive 50% yellow as much lighter than 50% blue)
  • New color properties in CSS level 4 will make color coding more human readable (HWB = Hue Whiteness Blackness)
  • There is room for much more improvement in web colors

Mind the Gap: Designing in the Space Between Devices - Josh Clark

  • Designing for the space between screens. Not content but tasks. Verbs not nouns
  • The technology is available today, we just haven't imagined the possibilities yet
  • Interfacing with machine is likely not going to change much (touch and mouse are great interfaces)
  • Physical things are beginning to have digital representations (avatars)
  • How about affecting how we interface with physical world and communicating that to our devices.
  • Software makes hardware scale, The endless possibilities

Web+: Can the Web Win the War Against Native Without Losing its Soul? - Bruce Lawson

  • Web technology has inherent strengths, despite the popularity of native apps
  • Web tech should not try to replicate — though it can learn from native. Build to the strengths of web
  • Progressive enhancement and interoperability make web accessible and global. Always accessible by everyone
  • Widgets failed as they were a poor imitation of native apps. They existed as a snapshot without the ability to update
  • W3C is built for accessibility and interoperability. This means that it is designed for low level functions. Can be complicated but powerful

How to Champion Ideas Back at Work - Scott Berkun

  • Great things are achieved in difficult circumstances
  • Success and acclaim only arrive once a project is complete
  • Charm and convincing people of your ideas is important!
  • A network increases your potential. Reach out and get advice to harness that potential
  • To enact change, start small with something you can excel at and expand from there

April 18, 2014 - Comments Off on Lightweight Drag and Drop for iOS with CSS3 Translate

Lightweight Drag and Drop for iOS with CSS3 Translate

This post explores issues we experienced with a recent project, involving jQuery UI’s draggables and how we solved it using CSS3 translate and javascript touch events.

In the midst of full production, we discovered an issue with iPad handling the combination of jQuery UI “draggables” and high quality images (for using jQuery UI with iPad touch events).

As production had already begun, we needed a shim to would work alongside what was already built, and replace the jQuery UI functionality on iOS devices.

We performed tests, sectioning off the drag and drops from the rest of the project and realized that, even one large background image severely affected the performance of the dragging animation on iOS devices. Scale that up to a production size eLearning platform and we suffered serious memory bleeds, causing Mobile Safari to crash instantly.

We googled far and wide but could find no solution. (HTML5 drag and drop would not fit the bill as it would require rebuilding everything we had done so far.)

And so we resolved to build a jQuery plugin and were pleasantly surprised to discover this undertaking was much simpler than first anticipated. Not only that, but our solution meant that, aside from changing the script which controlled these activities, we did not have to change any of the markup already written for dozens of pages.

Development

This blog post was a great jumping off point, it had done much of the hard work for us, showing us how to tie a touch event to a moving element. Despite being a great resource, the script animates with the “top” and “left” properties. While these work on all platforms, they use a lot of CPU power, too much for the poor iPad. And so we updated the code to use CSS3 translate. This change was light and day. iOS webkit hardware accelerates CSS translates through the GPU and the performance improvement was significant.

Next we needed to add functionality to drop a “draggable” inside a “droppable”. This was done in two steps. First we added an initialization for “droppable” elements which would calculate the coordinates of the “droppable” and store these values in the data attribute of that element. Next we added an event handler for dropping an element, which finds if the last touch event occurred inside the bounds of a “droppable”. If this is the case, then we translate the “draggable” to sit on top of the “droppable”.

Along the way we added certain functionality specific to our project such as populating an object named “dragInput”, which contains the placement of any dragged items and can then be compared against another object which holds the correct matches for a quiz style drag and drop activity.

Conclusion

Since integrating this into our project, I have tried to extend the plugin by adding mouse event listeners. There are limitations, such as dropping an element when the mouse escapes the bounds, despite the ‘mousedown’ event still being active. I have seen this behavior elsewhere. jQuery UI must use event listeners on the window to make up for this deficiency. Although I bemoan jQuery UI’s use of pre-CSS3 techniques, having tried to replicate the functionality with mouse events, I appreciate the depth of their project. The touch events were comparatively robust and behaved as expected.

CSS transforms are very powerful and although confusing at first glance, they give web developers exciting possibilities for creating native like experiences within browsers. By using transforms, our drag activities went from crashing the iPad to outperforming jQuery UI draggables on a desktop.

I hope this post proves helpful and I will continue to develop the plugin, as time and persistence permit.

Check out the github here.

Published by: georgebrassey in The Programming Mechanism
Tags: ,