Repository: cfpb/consumerfinance.gov

Issue:
Remove global.js code comment block
See https://github.com/cfpb/cfgov-refresh/pull/508#discussion_r29689594



Discussion:

Resolving patch:
diff --git a/_lib/wordpress_initiative_processor.py b/_lib/wordpress_initiative_processor.py
--- a/_lib/wordpress_initiative_processor.py
+++ b/_lib/wordpress_initiative_processor.py
@@ -2,18 +2,17 @@
 import json
 import os.path
 import requests
-import dateutil.parser
 
 
 def posts_at_url(url):
-    
+
     current_page = 1
     max_page = sys.maxint
 
     while current_page <= max_page:
         url = os.path.expandvars(url)
-        resp = requests.get(url, params={'page':current_page, 'count': '-1'})
-        results = json.loads(resp.content) 
+        resp = requests.get(url, params={'page': current_page, 'count': '-1'})
+        results = json.loads(resp.content)
         current_page += 1
         max_page = results['pages']
         for p in results['posts']:
@@ -33,31 +32,22 @@ def process_initiative(item):
     custom_fields = item['custom_fields']
 
     if custom_fields.get('related_office'):
-        item['related_office'] = \
-            custom_fields['related_office'][0]
-            
+        item['related_office'] = custom_fields['related_office'][0]
+
     # create list of initiative subinitiative dicts
-    item['subinitiatives'] = []
-    
-    for x in xrange(0,6):
-        subinitiative = {}
-        fields = ['header', 'desc']
-        subinitiative_links = []
-        
-        for field in fields:
-            field_name = 'subinitiative_%s_%s' % (field, str(x))
-            if field_name in custom_fields and custom_fields[field_name][0] != '':
-                subinitiative[field] = custom_fields[field_name][0]
-                
-        for y in xrange(0,5):
-            link_name = 'subinitiative_links_%s_%s' % (str(x), str(y))
-            if link_name in custom_fields:
-                subinitiative_links.append(custom_fields[link_name])
-
-        if subinitiative_links:
-            subinitiative['links'] = subinitiative_links
-
-        if subinitiative:
-            item['subinitiatives'].append(subinitiative)      
-    
+    related = []
+    for x in xrange(0, 5):
+        key = 'related_link_%s' % x
+        if key in custom_fields:
+            related.append(custom_fields[key])
+    if related:
+        item['related_links'] = related
+
+    del item['custom_fields']
+
+    if item['parent'] != 0:
+        item['has_parent'] = True
+    else:
+        item['has_parent'] = False
+
     return item
diff --git a/_lib/wordpress_office_processor.py b/_lib/wordpress_office_processor.py
--- a/_lib/wordpress_office_processor.py
+++ b/_lib/wordpress_office_processor.py
@@ -11,53 +11,53 @@ def posts_at_url(url):
     while current_page <= max_page:
 
         url = os.path.expandvars(url)
-        resp = requests.get(url, params={'page':current_page, 'count': '-1'})
-        results = json.loads(resp.content) 
+        resp = requests.get(url, params={'page': current_page, 'count': '-1'})
+        results = json.loads(resp.content)
         current_page += 1
         max_page = results['pages']
         for p in results['posts']:
             yield p
-     
+
 def documents(name, url, **kwargs):
-    
+
     for post in posts_at_url(url):
         yield process_office(post)
 
 
 def process_office(item):
-    
+
     item['_id'] = item['slug']
     custom_fields = item['custom_fields']
-    
+
     # get intro text & subscribe form data from custom fields
     for attr in ['intro_text', 'intro_subscribe_form', 'intro_govdelivery_code', 'related_contact']:
         if attr in custom_fields:
             item[attr] = custom_fields[attr][0]
-    
+
     # build top story dict
     top_story = {}
     for attr in ['top_story_head', 'top_story_desc']:
         if attr in custom_fields:
             top_story[attr] = custom_fields[attr][0]
-    
+
     # convert top story links into a proper list
     top_story_links = []
-    for x in xrange(0,5):
-      key = 'top_story_links_%s' % x
-      if key in custom_fields:
-          top_story_links.append(custom_fields[key])
-          
-    if top_story_links:     
+    for x in xrange(0, 5):
+        key = 'top_story_links_%s_link' % x
+        if key in custom_fields:
+            top_story_links.append(custom_fields[key])
+
+    if top_story_links:
         top_story['top_story_links'] = top_story_links
-        
+
     if top_story:
         item['top_story'] = top_story
-    
+
     # create list of office resource dicts
     item['resources'] = []
-    for x in xrange(0,4):
+    for x in xrange(0, 4):
         resource = {}
-        fields = ['head', 'desc', 'icon', 'link']
+        fields = ['title', 'desc', 'icon', 'link']
         for field in fields:
             field_name = 'resource_%s_%s' % (str(x), field)
             if field_name in custom_fields and custom_fields[field_name][0] != '':
@@ -65,9 +65,10 @@ def process_office(item):
                     resource[field] = custom_fields[field_name]
                 else:
                     resource[field] = custom_fields[field_name][0]
-                    
+
         if resource:
             item['resources'].append(resource)
 
-    return item
+    del item['custom_fields']
 
+    return item
diff --git a/_lib/wordpress_view_processor.py b/_lib/wordpress_view_processor.py
--- a/_lib/wordpress_view_processor.py
+++ b/_lib/wordpress_view_processor.py
@@ -9,22 +9,22 @@
 import dateutil.parser
 
 def posts_at_url(url):
-    
+
     url = os.path.expandvars(url)
     current_page = 1
     max_page = sys.maxint
 
     while current_page <= max_page:
 
-        resp = requests.get(url, params={'page':current_page})
-        results = json.loads(resp.content) 
+        resp = requests.get(url, params={'page': current_page})
+        results = json.loads(resp.content)
         current_page += 1
         max_page = results['pages']
         for p in results['posts']:
             yield p
-     
+
 def documents(name, url, **kwargs):
-    
+
     for view in posts_at_url(url):
         yield process_view(view)
 
@@ -38,8 +38,8 @@ def process_view(post):
         post['popular_posts'] = popular_posts
 
     # convert related links into a proper list
-    related =[]
-    for x in xrange(0,5):
+    related = []
+    for x in xrange(0, 5):
         key = 'related_link_%s' % x
         if key in custom_fields:
             related.append(custom_fields[key])
@@ -51,8 +51,9 @@ def process_view(post):
         hero_url = os.path.expandvars("$WORDPRESS/hero/" + hero_id + "/?json=1")
         response = requests.get(hero_url)
         hero_data = json.loads(response.content)
-        hero_data = hero_data['post']
-        hero_data['related_posts'] = hero_data['custom_fields']['related_post']
-        post['hero'] = hero_data
+        if hero_data['status'] is 'ok':
+            hero_data = hero_data['post']
+            hero_data['related_posts'] = hero_data['custom_fields']['related_post']
+            post['hero'] = hero_data
 
     return post


Test patch:
diff --git a/_tests/unit_tests/.eslintrc b/_tests/unit_tests/.eslintrc
new file mode 100644
--- /dev/null
+++ b/_tests/unit_tests/.eslintrc
@@ -0,0 +1,5 @@
+env:
+  node: true
+  mocha: true
+rules:
+  no-unused-expressions: 0
diff --git a/_tests/unit_tests/fixtures/forms.html b/_tests/unit_tests/fixtures/forms.html
new file mode 100644
--- /dev/null
+++ b/_tests/unit_tests/fixtures/forms.html
@@ -0,0 +1,135 @@
+<form id="email-subscribe-form" action="/subscriptions/new/" method="POST" enctype="application/x-www-form-urlencoded">
+
+    <div class="form-group">
+        <label for="email-subscribe-form_email-1">
+            Email address
+        </label>
+        <input id="email-subscribe-form_email-1" type="email" name="email1" placeholder="example@mail.com" required="">
+    </div>
+    <p class="short-desc u-mt10">
+        The information you provide will permit the Consumer Financial
+        Protection Bureau to process your request or inquiry.
+        <a href="/privacy-policy/">See More</a>
+    </p>
+    <div class="form-group">
+        <input type="hidden" name="code" value="USCFPB_91">
+        <input class="btn" type="submit" value="Sign up">
+    </div>
+
+</form>
+
+<form class="js-validate-filters" method="get">
+
+    <div class="form-l form-l__float form-l__flush">
+
+        <div class="form-l_col form-l_col-1-3">
+            <div class="form-group required-check-group">
+                <label class="form-label-header">
+                    Calendars
+                </label>
+                <label class="form-group_item custom-input_label is-enabled"><span class="custom-input_text">Richard Cordray
+                </span><input class="custom-input custom-input_input" type="checkbox" name="filter_calendar" value="Richard Cordray"><span class="custom-input_checkbox"></span></label>
+                <label class="form-group_item custom-input_label is-enabled"><span class="custom-input_text">Steve Antonakes
+                </span><input class="custom-input custom-input_input" type="checkbox" name="filter_calendar" value="Steve Antonakes"><span class="custom-input_checkbox"></span></label>
+                <label class="form-group_item custom-input_label is-enabled"><span class="custom-input_text">Raj Date
+                </span><input class="custom-input custom-input_input" type="checkbox" name="filter_calendar" value="Raj Date"><span class="custom-input_checkbox"></span></label>
+                <label class="form-group_item custom-input_label is-enabled"><span class="custom-input_text">Elizabeth Warren
+                </span><input class="custom-input custom-input_input" type="checkbox" name="filter_calendar" value="Elizabeth Warren"><span class="custom-input_checkbox"></span></label>
+            </div>
+        </div>
+
+        <div class="form-l_col form-l_col-2-3">
+          <div class="form-l form-l__flush">
+            <label class="form-l_col-1 form-label-header">
+                Date range
+            </label>
+
+            <div class="form-l_col form-l_col-1-2 js-filter_range-date-wrapper" style="display: none;">
+                <label for="filter_range-date-gte">
+                    From:
+                </label>
+                <input class="js-filter_range-date js-filter_range-date__gte" id="filter_range-date-gte" name="filter_range_date_gte" type="text" value="" placeholder="YYYY-MM">
+            </div>
+
+            <div class="form-l_col form-l_col-1-2 input-group js-filter_range-date-replacement" style="">
+                <label for="filter_from-month">
+                    From:
+                </label>
+                <div class="input-group_item custom-select is-enabled">
+                    <select class="form-input-month js-filter_month custom-select_select" id="filter_from-month" style="opacity: 0;">
+                        <option value="">Month</option>
+                        <option value="01">Jan</option>
+                        <option value="02">Feb</option>
+                        <option value="03">Mar</option>
+                        <option value="04">Apr</option>
+                        <option value="05">May</option>
+                        <option value="06">Jun</option>
+                        <option value="07">Jul</option>
+                        <option value="08">Aug</option>
+                        <option value="09">Sep</option>
+                        <option value="10">Oct</option>
+                        <option value="11">Nov</option>
+                        <option value="12">Dec</option>
+                    </select>
+                    <span class="custom-select_icon cf-icon cf-icon-down"></span>
+                <span class="custom-select_text custom-select_placeholder">Month</span></div>
+                <div class="input-group_item custom-select is-enabled">
+                    <select class="form-input_year js-filter_year custom-select_select" id="filter_from-year" style="opacity: 0;">
+                        <option value="" selected="selected">Year</option><option value="2011">2011</option><option value="2012">2012</option><option value="2013">2013</option><option value="2014">2014</option><option value="2015">2015</option></select>
+                    <span class="custom-select_icon cf-icon cf-icon-down"></span>
+                <span class="custom-select_text custom-select_placeholder">Year</span></div>
+            </div>
+
+            <div class="form-l_col form-l_col-1-2 js-filter_range-date-wrapper" style="display: none;">
+                <label for="filter_range-date-lte">
+                    To:
+                </label>
+                <input class="js-filter_range-date js-filter_range-date__lte" id="filter_range-date-lte" name="filter_range_date_lte" type="text" value="" placeholder="YYYY-MM">
+            </div>
+
+            <div class="form-l_col form-l_col-1-2 input-group js-filter_range-date-replacement" style="">
+                <label for="filter_to-month">
+                    To:
+                </label>
+                <div class="custom-select input-group_item is-enabled">
+                    <select class="form-input-month js-filter_month custom-select_select" id="filter_to-month" style="opacity: 0;">
+                        <option value="">Month</option>
+                        <option value="01">Jan</option>
+                        <option value="02">Feb</option>
+                        <option value="03">Mar</option>
+                        <option value="04">Apr</option>
+                        <option value="05">May</option>
+                        <option value="06">Jun</option>
+                        <option value="07">Jul</option>
+                        <option value="08">Aug</option>
+                        <option value="09">Sep</option>
+                        <option value="10">Oct</option>
+                        <option value="11">Nov</option>
+                        <option value="12">Dec</option>
+                    </select>
+                    <span class="custom-select_icon cf-icon cf-icon-down"></span>
+                <span class="custom-select_text custom-select_placeholder">Month</span></div>
+                <div class="custom-select input-group_item is-enabled">
+                    <select class="form-input_year js-filter_year custom-select_select" id="filter_to-year" style="opacity: 0;">
+                        <option value="" selected="selected">Year</option>
+                        <option value="2011">2011</option>
+                        <option value="2012">2012</option>
+                        <option value="2013">2013</option>
+                        <option value="2014">2014</option>
+                        <option value="2015">2015</option>
+                    </select>
+                    <span class="custom-select_icon cf-icon cf-icon-down"></span>
+                <span class="custom-select_text custom-select_placeholder">Year</span></div>
+            </div>
+
+          </div>
+        </div>
+
+    </div> <!-- END .form-l__flush -->
+
+    <div class="form-actions form-actions__right-on-med">
+        <input class="btn btn__warning btn__link form-actions_item js-form_clear" type="button" value="Clear filters">
+        <input class="btn form-actions_item" type="submit" value="Apply filters">
+    </div>
+
+</form>
\ No newline at end of file
diff --git a/_tests/unit_tests/modules/cf_notifier-spec.js b/_tests/unit_tests/modules/cf_notifier-spec.js
new file mode 100644
--- /dev/null
+++ b/_tests/unit_tests/modules/cf_notifier-spec.js
@@ -0,0 +1,42 @@
+'use strict';
+var chai = require( 'chai' );
+var sinon = require( 'sinon' );
+var expect = chai.expect;
+var jsdom = require( 'mocha-jsdom' );
+
+describe( 'CFNotifier', function() {
+  var $, $form;
+
+  jsdom( {
+    file: '_tests/unit_tests/fixtures/forms.html',
+    console: false
+  } );
+
+  before( function() {
+    $ = require( 'jquery' );
+    require( '../../../src/static/js/modules/jquery/cf_notifier.js' ).init();
+    $form = $( '#email-subscribe-form' );
+    $form.cf_notifier();
+  } );
+
+  beforeEach( function() {
+  } );
+
+  afterEach( function() {
+  } );
+
+  it( 'should create a notification', function() {
+    $form.trigger( 'cf_notifier:notify' );
+    expect(
+      $( '.cf-notification' )
+    ).to.have.length( 1 );
+  } );
+
+  it( 'should not create an additional notification', function() {
+    $form.trigger( 'cf_notifier:notify' );
+    expect(
+      $( '.cf-notification' )
+    ).to.have.length( 2 );
+  } );
+
+} );
diff --git a/_tests/unit_tests/modules/footer-button-spec.js b/_tests/unit_tests/modules/footer-button-spec.js
new file mode 100644
--- /dev/null
+++ b/_tests/unit_tests/modules/footer-button-spec.js
@@ -0,0 +1,60 @@
+'use strict';
+var chai = require( 'chai' );
+var sinon = require( 'sinon' );
+var expect = chai.expect;
+var jsdom = require( 'mocha-jsdom' );
+
+describe( 'The Footer Return-to-Top Button', function() {
+  var $, footerButton, sandbox;
+
+  jsdom();
+
+  before( function() {
+    $ = require( 'jquery' );
+    footerButton = require( '../../../src/static/js/modules/footer-button.js' );
+    sandbox = sinon.sandbox.create();
+  } );
+
+  beforeEach( function() {
+    // Adding a simplified version of the thing we want to test.
+    // Then calling the jQuery to test after
+    $( 'body' ).html( $( '<a class="js-return-to-top"' +
+                            'href="http://www.google.com/">' +
+                            'Back to top' +
+                          '</a>' ) );
+  } );
+
+  afterEach( function() {
+    sandbox.restore();
+  } );
+
+  it( 'should not trigger an animate before an init', function() {
+    $( 'body' ).scrollTop( 500 );
+    var AnimateSpy = sandbox.spy( $.prototype, 'animate' );
+
+    $( '.js-return-to-top' ).trigger( 'click' );
+    expect( AnimateSpy.called ).to.not.be.ok;
+  } );
+
+  it( 'should trigger animate function when clicked', function() {
+    footerButton.init();
+    $( 'body' ).scrollTop( 500 );
+    var animateSpy = sandbox.spy( $.prototype, 'animate' );
+
+    $( '.js-return-to-top' ).trigger( 'click' );
+    expect( animateSpy.called ).to.be.ok;
+  } );
+
+  it( 'should not navigate away from the page', function() {
+    $( '.js-return-to-top' ).trigger( 'click' );
+    expect( window.location.href ).to.not.equal( 'http://www.google.com/' );
+  } );
+
+  it( 'should remove handlers when item is removed', function() {
+    var animateSpy = sinon.spy( $.prototype, 'animate' );
+    $( '.js-return-to-top' ).remove();
+    $( '.js-return-to-top' ).trigger( 'click' );
+    expect( animateSpy.called ).to.not.be.ok;
+  } );
+
+} );