civic_aide 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Error" do
4
+
5
+ it "matches the error message" do
6
+ expect { raise APIKeyNotSet}.to raise_error(APIKeyNotSet, 'Missing a required Google API key.')
7
+ expect { raise ElectionIdMissing}.to raise_error(ElectionIdMissing, 'Missing a required election id.')
8
+ expect { raise NoStreetSegmentFound}.to raise_error(NoStreetSegmentFound, 'The API currently has no information about what electoral precinct and/or district this address belongs to. It may be that we are still sourcing/processing new data, or that there are no voters who have registered to vote at this address.')
9
+ expect { raise AddressUnparseable}.to raise_error(AddressUnparseable, 'The requested address is not formatted correctly or cannot be geocoded (i.e. the Google Maps API does not know anything about this address).')
10
+ expect { raise NoAddressParameter}.to raise_error(NoAddressParameter, 'No address was provided.')
11
+ expect { raise MultipleStreetSegmentsFound}.to raise_error(MultipleStreetSegmentsFound, 'The API cannot find information for the specified address, but it has information about nearby addresses. The user should contact their election official for more information.')
12
+ expect { raise ElectionOver}.to raise_error(ElectionOver, 'The requested election is over. API results for the election are no longer available. Make an electionQuery to find an id for an upcoming election.')
13
+ expect { raise ElectionUnknown}.to raise_error(ElectionUnknown, 'The requested election id is invalid. Make an electionQuery to find a valid id.')
14
+ expect { raise InternalLookupFailure}.to raise_error(InternalLookupFailure, 'An unspecified error occurred processing the request.')
15
+ end
16
+
17
+ end
18
+
19
+ describe APIError do
20
+ it { should be_kind_of(StandardError) }
21
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hash do
4
+
5
+ context ".rubyify_keys" do
6
+ before do
7
+ @hash1 = {"testOne" => "1", "TestTwo" => "2", :testThree => 3, :TestFour => 4, :testFiveSix => 56}
8
+ @hash1.rubyify_keys!
9
+ @hash2 = {"test_one" => "1", "test_two" => "2", "test_three" => 3, "test_four" => 4, "test_five_six" => 56}
10
+ end
11
+
12
+ it "should convert camelcased keys to underscored keys" do
13
+ expect(@hash1).to eq(@hash2)
14
+ end
15
+
16
+ it "should not rubify Open Civic Data identifiers" do
17
+ ocd = {"ocd-division/country:us/state:nc/county:durham" => "test"}
18
+ ocd2 = ocd.clone
19
+ ocd.rubyify_keys!
20
+ expect(ocd).to eq(ocd2)
21
+ end
22
+
23
+ end
24
+
25
+ context ".except" do
26
+
27
+ it "should remove the correct item" do
28
+ deleted = {:one => "hello", :two => "hello"}
29
+ deleted = deleted.except(:two)
30
+ expect(deleted).to eq({:one => "hello"})
31
+ end
32
+
33
+ end
34
+
35
+ context ".except!" do
36
+
37
+ it "should remove the correct item" do
38
+ deleted = {:one => "hello", :two => "hello"}
39
+ deleted.except!(:two)
40
+ expect(deleted).to eq({:one => "hello"})
41
+ end
42
+
43
+ end
44
+
45
+ context ".change_zip!" do
46
+
47
+ it "changes zip in simple hash" do
48
+ one = {"zip" => "test", "hello" => "test"}
49
+ one.change_zip!
50
+ expect(one).to eq({"zipCode" => "test", "hello" => "test"})
51
+ end
52
+
53
+ it "changes zip in complex hash" do
54
+ two = {"zip" => "test", "hello" => "test", "three" => {"zip" => "hello"}}
55
+ two.change_zip!
56
+ expect(two).to eq({"zipCode" => "test", "hello" => "test", "three" => {"zipCode" => "hello"}})
57
+ end
58
+
59
+ end
60
+
61
+ end
@@ -0,0 +1,137 @@
1
+ require 'spec_helper'
2
+
3
+ describe CivicAide::Representatives do
4
+
5
+ before do
6
+ @client = CivicAide::Client.new("AIzaSyDWJSisG_4Azd6nVJTU5gdKPiKKTCovupY")
7
+ end
8
+
9
+ describe "get info for specific election" do
10
+
11
+ let(:info) { @client.representatives.at('320 E Chapel Hill St, Durham NC, 27701') }
12
+
13
+ before do
14
+ VCR.insert_cassette 'representatives/single', :record => :new_episodes
15
+ end
16
+
17
+ after do
18
+ VCR.eject_cassette
19
+ end
20
+
21
+ it "must parse the response from JSON to Hash" do
22
+ expect(info).to be_a Hash
23
+ end
24
+
25
+ it "must remove kind" do
26
+ expect(info).to_not respond_to(:kind)
27
+ end
28
+
29
+ it "should have normalized input" do
30
+ expect(info).to respond_to(:normalized_input)
31
+ end
32
+
33
+ it "should have normalized input hash" do
34
+ expect(info.normalized_input).to be_a Hash
35
+ end
36
+
37
+ it "should have normalized input line 1" do
38
+ expect(info.normalized_input.line1).to eq("320 e chapel hill st")
39
+ end
40
+
41
+ it "should have normalized input city" do
42
+ expect(info.normalized_input.city).to eq("durham")
43
+ end
44
+
45
+ it "should have normalized input state" do
46
+ expect(info.normalized_input.state).to eq("NC")
47
+ end
48
+
49
+ it "should have normalized input zip" do
50
+ expect(info.normalized_input.zip_code).to eq("27701")
51
+ end
52
+
53
+ it "should respond to divisions" do
54
+ expect(info).to respond_to(:divisions)
55
+ end
56
+
57
+ describe "individual division area" do
58
+
59
+ let(:area) { info.divisions['ocd-division/country:us/state:nc/county:durham'] }
60
+
61
+ it "should have name" do
62
+ expect(area.name).to eq("Durham County")
63
+ end
64
+
65
+ it "should have scope" do
66
+ expect(area.scope).to eq("countywide")
67
+ end
68
+
69
+ it "should have office ids" do
70
+ expect(area.office_ids).to be_a Array
71
+ end
72
+
73
+ it "should have division areas" do
74
+ expect(area).to be_a Hash
75
+ end
76
+
77
+ end
78
+
79
+ describe "individual offices" do
80
+
81
+ let(:office) { info.offices.o1 }
82
+
83
+ it "should have name" do
84
+ expect(office.name).to eq("Clerk of Courts")
85
+ end
86
+
87
+ it "should have level" do
88
+ expect(office.level).to eq("county")
89
+ end
90
+
91
+ it "should have official ids" do
92
+ expect(office.official_ids).to be_a Array
93
+ end
94
+
95
+ end
96
+
97
+ describe "individual official" do
98
+
99
+ let(:official) { info.officials.p9 }
100
+
101
+ it "should have officials" do
102
+ expect(info).to respond_to(:officials)
103
+ end
104
+
105
+ it "should have name" do
106
+ expect(official.name).to eq("Pat McCrory")
107
+ end
108
+
109
+ it "should have party" do
110
+ expect(official.party).to eq("Republican")
111
+ end
112
+
113
+ it "should have photo url" do
114
+ expect(official.photo_url).to eq("http://www.governor.state.nc.us/sites/all/themes/govpat/images/GovPatMcCrory.jpg")
115
+ end
116
+
117
+ it "should have addresses" do
118
+ expect(official.address).to be_a Array
119
+ end
120
+
121
+ it "should have phones" do
122
+ expect(official.phones).to be_a Array
123
+ end
124
+
125
+ it "should have website urls" do
126
+ expect(official.urls).to be_a Array
127
+ end
128
+
129
+ it "should have social media channels" do
130
+ expect(official.channels).to be_a Array
131
+ end
132
+
133
+ end
134
+
135
+ end
136
+
137
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe String do
4
+
5
+ context ".underscore" do
6
+ before do
7
+ @camel_case_strings = ["camelCase", "CamelCase", "stringTwoHumps", "StringHasThreeHumps"]
8
+ @underscore_strings = ["camel_case", "camel_case", "string_two_humps", "string_has_three_humps"]
9
+ end
10
+
11
+ it "should convert camelcase strings to underscored strings" do
12
+ @camel_case_strings.collect{|s| s = s.underscore}.should == @underscore_strings
13
+ end
14
+ end
15
+
16
+ end
@@ -0,0 +1,28 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+
8
+ require 'civic_aide'
9
+ require 'vcr'
10
+
11
+ RSpec.configure do |config|
12
+ config.treat_symbols_as_metadata_keys_with_true_values = true
13
+ config.run_all_when_everything_filtered = true
14
+ config.filter_run :focus
15
+
16
+ # Run specs in random order to surface order dependencies. If you find an
17
+ # order dependency and want to debug it, you can fix the order by providing
18
+ # the seed, which is printed after each run.
19
+ # --seed 1234
20
+ # config.order = 'random'
21
+ end
22
+
23
+ VCR.configure do |c|
24
+ #the directory where your cassettes will be saved
25
+ c.cassette_library_dir = 'spec/vcr'
26
+ # your HTTP request service. You can also use fakeweb, webmock, and more
27
+ c.hook_into :webmock
28
+ end
@@ -0,0 +1,63 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://www.googleapis.com/civicinfo/us_v1/elections?key=AIzaSyDWJSisG_4Azd6nVJTU5gdKPiKKTCovupY&prettyPrint=false
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ User-Agent:
13
+ - CivicAide Ruby gem v0.0.1
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Expires:
20
+ - Thu, 26 Dec 2013 22:31:21 GMT
21
+ Date:
22
+ - Thu, 26 Dec 2013 22:31:21 GMT
23
+ Cache-Control:
24
+ - private, max-age=0, must-revalidate, no-transform
25
+ Etag:
26
+ - '"AkiRpOnd7sKoopyUaI9w1UXzdBI/6fWb4ADfTC_VR0ralkU4RO9X0Rc"'
27
+ Content-Type:
28
+ - application/json; charset=UTF-8
29
+ X-Content-Type-Options:
30
+ - nosniff
31
+ X-Frame-Options:
32
+ - SAMEORIGIN
33
+ X-Xss-Protection:
34
+ - 1; mode=block
35
+ Server:
36
+ - GSE
37
+ Alternate-Protocol:
38
+ - 443:quic
39
+ Transfer-Encoding:
40
+ - chunked
41
+ body:
42
+ encoding: UTF-8
43
+ string: '{"kind":"civicinfo#electionsQueryResponse","elections":[{"id":"2000","name":"VIP
44
+ Test Election","electionDay":"2015-06-06"},{"id":"4000","name":"U.S. 2012
45
+ General Election","electionDay":"2012-11-06"},{"id":"4001","name":"Los Angeles
46
+ City Primary","electionDay":"2013-03-05"},{"id":"4002","name":"California
47
+ Combined Special Elections","electionDay":"2013-03-12"},{"id":"4003","name":"South
48
+ Carolina HD-01 Special Primary","electionDay":"2013-03-19"},{"id":"4004","name":"California
49
+ Special Election SD-32","electionDay":"2013-05-14"},{"id":"4005","name":"Los
50
+ Angeles City Election","electionDay":"2013-05-21"},{"id":"4006","name":"South
51
+ Carolina HD-01","electionDay":"2013-05-07"},{"id":"4007","name":"New Jersey
52
+ Primary","electionDay":"2013-06-04"},{"id":"4008","name":"Virginia Primary","electionDay":"2013-06-11"},{"id":"4009","name":"Delaware
53
+ Presidential Primary 2012","electionDay":"2013-09-01"},{"id":"4010","name":"NYC
54
+ 2013 Mayoral Primary","electionDay":"2013-09-10"},{"id":"4011","name":"NYC
55
+ 2013 Mayoral Primary Runoff","electionDay":"2013-10-01"},{"id":"4012","name":"NJ
56
+ 2013 U.S. Senate Special Election","electionDay":"2013-10-16"},{"id":"4013","name":"NYC
57
+ 2013 Mayoral Election","electionDay":"2013-11-05"},{"id":"4014","name":"NJ
58
+ State Election","electionDay":"2013-11-05"},{"id":"4015","name":"VA State
59
+ Election","electionDay":"2013-11-05"},{"id":"4016","name":"MN 2013 Municipal
60
+ General","electionDay":"2013-11-05"}]}'
61
+ http_version:
62
+ recorded_at: Thu, 26 Dec 2013 22:31:22 GMT
63
+ recorded_with: VCR 2.5.0
@@ -0,0 +1,83 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://www.googleapis.com/civicinfo/us_v1/voterinfo/4015/lookup?key=AIzaSyDWJSisG_4Azd6nVJTU5gdKPiKKTCovupY&officialOnly=false&prettyPrint=false
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"address":"4910 Willet Drive, Annandale, VA 22003"}'
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ User-Agent:
13
+ - CivicAide Ruby gem v0.0.1
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Cache-Control:
20
+ - no-cache, no-store, max-age=0, must-revalidate
21
+ Pragma:
22
+ - no-cache
23
+ Expires:
24
+ - Fri, 01 Jan 1990 00:00:00 GMT
25
+ Date:
26
+ - Fri, 27 Dec 2013 16:20:02 GMT
27
+ Etag:
28
+ - '"AkiRpOnd7sKoopyUaI9w1UXzdBI/rfJe2ukXTYNjeHzUnUQ4G4gDa84"'
29
+ Content-Type:
30
+ - application/json; charset=UTF-8
31
+ X-Content-Type-Options:
32
+ - nosniff
33
+ X-Frame-Options:
34
+ - SAMEORIGIN
35
+ X-Xss-Protection:
36
+ - 1; mode=block
37
+ Server:
38
+ - GSE
39
+ Alternate-Protocol:
40
+ - 443:quic
41
+ Transfer-Encoding:
42
+ - chunked
43
+ body:
44
+ encoding: UTF-8
45
+ string: '{"kind":"civicinfo#voterInfoResponse","status":"success","election":{"id":"4015","name":"VA
46
+ State Election","electionDay":"2013-11-05"},"normalizedInput":{"line1":"4910
47
+ willet dr","city":"annandale","state":"VA","zip":"22003"},"contests":[{"type":"general","special":"no","office":"Lieutenant
48
+ Governor","district":{"name":"Statewide","scope":"statewide"},"ballotPlacement":"5","candidates":[{"name":"Ralph
49
+ S. Northam","party":"Democrat","candidateUrl":"http://www.northamforlg.com","phone":"7576954188","email":"ralph@ralphnortham.com"},{"name":"E.
50
+ W. Jackson","party":"Republican","candidateUrl":"http://www.jacksonforlg.com","phone":"7578024246","email":"jackson@jacksonforlg.com"}],"sources":[{"name":"Voting
51
+ Information Project","official":true}]},{"type":"general","special":"no","office":"Governor","district":{"name":"Statewide","scope":"statewide"},"ballotPlacement":"4","candidates":[{"name":"Ken
52
+ T. Cuccinelli II","party":"Republican","candidateUrl":"http://www.cuccinelli.com","phone":"8047863808","email":"ken@cuccinelli.com"},{"name":"Robert
53
+ C. Sarvis","party":"Libertarian","candidateUrl":"http://www.robertsarvis.com","email":"info@robertsarvis.com"},{"name":"Terry
54
+ R. McAuliffe","party":"Democrat","candidateUrl":"http://www.terrymcauliffe.com","phone":"7038227604","email":"info@terrymcauliffe.com"}],"sources":[{"name":"Voting
55
+ Information Project","official":true}]},{"type":"general","special":"no","office":"Attorney
56
+ General","district":{"name":"Statewide","scope":"statewide"},"ballotPlacement":"6","candidates":[{"name":"Mark
57
+ D. Obenshain","party":"Republican","candidateUrl":"http://www.markobenshain.com","phone":"5404371451","email":"campaign@markobenshain.com"},{"name":"Mark
58
+ R. Herring","party":"Democrat","candidateUrl":"http://www.herringforag.com","phone":"7036699090","email":"kevin@herringforag.com"}],"sources":[{"name":"Voting
59
+ Information Project","official":true}]},{"type":"general","special":"no","office":"Member
60
+ House of Delegates","district":{"name":"039","scope":"stateLower","id":"39"},"ballotPlacement":"8","candidates":[{"name":"Vivian
61
+ E. Watts","party":"Democrat","candidateUrl":"http://www.vivianwatts.com","phone":"7039782989","email":"vwatts@erols.com"},{"name":"Joe
62
+ G. Bury","party":"Republican","candidateUrl":"http://www.joebury.com","phone":"7033078221","email":"jgbury@hotmail.com"}],"sources":[{"name":"Voting
63
+ Information Project","official":true}]},{"type":"general","special":"no","office":"Sheriff","district":{"name":"FAIRFAX
64
+ COUNTY"},"ballotPlacement":"11","candidates":[{"name":"Stacey Ann Kincaid","party":"Democrat","candidateUrl":"http://staceykincaid.com","phone":"7039381658","email":"Kincaidforsheriff@gmail.com"},{"name":"Christopher
65
+ F. DeCarlo","party":"Independent","candidateUrl":"http://www.honestyandethics.com","phone":"7035736160","email":"cdecarlo@fairfaxpropane.com"},{"name":"Bryan
66
+ A. /B. A./ Wolfe","party":"Republican","candidateUrl":"http://www.wolfeforsheriff.com","phone":"7035436360","email":"fairfaxwolfe@yahoo.com"},{"name":"Robert
67
+ A. Rivera","party":"Independent","phone":"7039783034","email":"riveraforsheriff@gmail.com"}],"sources":[{"name":"Voting
68
+ Information Project","official":true}]},{"type":"Referendum","special":"no","office":"School
69
+ Bonds","district":{"name":"FAIRFAX COUNTY","id":"59"},"ballotPlacement":"9999","sources":[{"name":"Voting
70
+ Information Project","official":true}]}],"state":[{"name":"Virginia","electionAdministrationBody":{"name":"State
71
+ Board of Elections","electionInfoUrl":"http://www.sbe.virginia.gov/","electionRegistrationUrl":"https://www.vote.virginia.gov/","electionRegistrationConfirmationUrl":"https://www.vote.virginia.gov/","absenteeVotingInfoUrl":"http://www.sbe.virginia.gov/absenteevoting.html","votingLocationFinderUrl":"https://www.vote.virginia.gov/","ballotInfoUrl":"https://www.vote.virginia.gov/","electionRulesUrl":"http://www.sbe.virginia.gov/","physicalAddress":{"locationName":"State
72
+ Board of Elections","line1":"Washington Building First Floor","line2":"1100
73
+ Bank Street","city":"Richmond","state":"VA","zip":"23219"}},"local_jurisdiction":{"name":"FAIRFAX
74
+ COUNTY","electionAdministrationBody":{"name":"FAIRFAX COUNTY","electionInfoUrl":"http://www.fairfaxcounty.gov/elections","electionRegistrationUrl":"http://www.vote.virginia.gov","electionRegistrationConfirmationUrl":"http://www.vote.virginia.gov","absenteeVotingInfoUrl":"http://www.vote.virginia.gov","votingLocationFinderUrl":"http://www.vote.virginia.gov","ballotInfoUrl":"http://www.vote.virginia.gov","electionRulesUrl":"http://www.vote.virginia.gov","hoursOfOperation":"8:00
75
+ a.m. to 4:30 p.m Monday-Wednesday and Friday and 8:00 a.m. to 7:00 p.m. Thursday","physicalAddress":{"locationName":"FAIRFAX
76
+ COUNTY","line1":"OFFICE OF ELECTIONS","line2":"12000 GOVERNMENT CENTER PKWY","line3":"SUITE
77
+ 323","city":"FAIRFAX","state":"VA","zip":"22035-0081"},"electionOfficials":[{"name":"CAMERON
78
+ P. QUINN","title":"General Registrar Physical","officePhoneNumber":"7033244715","emailAddress":"cameronquinn@fairfaxcounty.gov"}]},"sources":[{"name":"Voting
79
+ Information Project","official":true}]},"sources":[{"name":"Voting Information
80
+ Project","official":true}]}]}'
81
+ http_version:
82
+ recorded_at: Fri, 27 Dec 2013 16:20:05 GMT
83
+ recorded_with: VCR 2.5.0
@@ -0,0 +1,106 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://www.googleapis.com/civicinfo/us_v1/representatives/lookup?includeOffices=true&key=AIzaSyDWJSisG_4Azd6nVJTU5gdKPiKKTCovupY&prettyPrint=false
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"address":"320 E Chapel Hill St, Durham NC, 27701"}'
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ User-Agent:
13
+ - CivicAide Ruby gem v0.0.1
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Cache-Control:
20
+ - no-cache, no-store, max-age=0, must-revalidate
21
+ Pragma:
22
+ - no-cache
23
+ Expires:
24
+ - Fri, 01 Jan 1990 00:00:00 GMT
25
+ Date:
26
+ - Sat, 28 Dec 2013 06:45:05 GMT
27
+ Etag:
28
+ - '"AkiRpOnd7sKoopyUaI9w1UXzdBI/uUqEGRPWFFqmpcAIIuYHjnGWvh8"'
29
+ Content-Type:
30
+ - application/json; charset=UTF-8
31
+ X-Content-Type-Options:
32
+ - nosniff
33
+ X-Frame-Options:
34
+ - SAMEORIGIN
35
+ X-Xss-Protection:
36
+ - 1; mode=block
37
+ Server:
38
+ - GSE
39
+ Alternate-Protocol:
40
+ - 443:quic
41
+ Transfer-Encoding:
42
+ - chunked
43
+ body:
44
+ encoding: UTF-8
45
+ string: '{"kind":"civicinfo#representativeInfoResponse","status":"success","normalizedInput":{"line1":"320
46
+ e chapel hill st","city":"durham","state":"NC","zip":"27701"},"divisions":{"ocd-division/country:us/state:nc/county:durham":{"name":"Durham
47
+ County","scope":"countywide","officeIds":["O0","O1","O2","O3","O4"]},"ocd-division/country:us/state:nc/place:durham":{"name":"Durham
48
+ city","scope":"citywide"},"ocd-division/country:us/state:nc":{"name":"North
49
+ Carolina","scope":"statewide","officeIds":["O5","O6","O7","O8","O9","Oa","Ob","Oc","Od","Oe","Of"]},"ocd-division/country:us/state:nc/cd:1":{"name":"North
50
+ Carolina''s 1st congressional district","scope":"congressional","officeIds":["O10"]},"ocd-division/country:us":{"name":"United
51
+ States","scope":"national","officeIds":["O11","O12"]}},"offices":{"O0":{"name":"Sheriff","level":"county","officialIds":["P0"]},"O1":{"name":"Clerk
52
+ of Courts","level":"county","officialIds":["P1"]},"O2":{"name":"County Commission","level":"county","officialIds":["P2","P3","P4","P5","P6"]},"O3":{"name":"District
53
+ Attorney","level":"county","officialIds":["P7"]},"O4":{"name":"Register of
54
+ Deeds","level":"county","officialIds":["P8"]},"O5":{"name":"Governor","level":"state","officialIds":["P9"]},"O6":{"name":"State
55
+ Auditor","level":"state","officialIds":["P10"]},"O7":{"name":"State Treasurer","level":"state","officialIds":["P11"]},"O8":{"name":"Attorney
56
+ General","level":"state","officialIds":["P12"]},"O9":{"name":"Secretary of
57
+ State","level":"state","officialIds":["P13"]},"Oa":{"name":"Lieutenant Governor","level":"state","officialIds":["P14"]},"Ob":{"name":"United
58
+ States Senate","level":"federal","officialIds":["P15","P16"]},"Oc":{"name":"Commissioner
59
+ of Labor","level":"state","officialIds":["P17"]},"Od":{"name":"Insurance Commissioner","level":"state","officialIds":["P18"]},"Oe":{"name":"Commissioner
60
+ of Agriculture","level":"state","officialIds":["P19"]},"Of":{"name":"Superintendent
61
+ of Public Instruction","level":"state","officialIds":["P20"]},"O10":{"name":"United
62
+ States House of Representatives NC-01","level":"federal","officialIds":["P21"]},"O11":{"name":"President","level":"federal","officialIds":["P22"]},"O12":{"name":"Vice
63
+ President","level":"federal","officialIds":["P23"]}},"officials":{"P0":{"name":"Michael
64
+ Andrews","party":"Unknown","urls":["http://dconc.gov/index.aspx?page=475"]},"P1":{"name":"Archie
65
+ L. Smith III","party":"Unknown","urls":["http://www.nccourts.org/County/Durham/Staff/Clerk.asp"]},"P2":{"name":"Brenda
66
+ Howerton","party":"Unknown","urls":["http://dconc.gov/index.aspx?page=52"]},"P3":{"name":"Michael
67
+ Page","party":"Unknown","urls":["http://dconc.gov/index.aspx?page=52"]},"P4":{"name":"Wendy
68
+ Jacobs","party":"Unknown","urls":["http://dconc.gov/index.aspx?page=52"]},"P5":{"name":"Fred
69
+ Foster, Jr.","party":"Unknown","urls":["http://dconc.gov/index.aspx?page=52"]},"P6":{"name":"Ellen
70
+ Reckhow","party":"Unknown","urls":["http://dconc.gov/index.aspx?page=52"]},"P7":{"name":"Leon
71
+ Stanback","party":"Unknown","urls":["http://www.nccourts.org/County/Durham/Staff/DistrictAttorney.asp"]},"P8":{"name":"Willie
72
+ Covington","party":"Unknown","urls":["http://dconc.gov/index.aspx?page=455"]},"P9":{"name":"Pat
73
+ McCrory","address":[{"line1":"Office of the Governor 20301 Mail Service Center","city":"raleigh","state":"NC","zip":"27699"}],"party":"Republican","phones":["(919)
74
+ 814-2000"],"urls":["http://www.governor.nc.gov/"],"photoUrl":"http://www.governor.state.nc.us/sites/all/themes/govpat/images/GovPatMcCrory.jpg","channels":[{"type":"Facebook","id":"GovernorPat"},{"type":"Twitter","id":"PatMcCroryNC"}]},"P10":{"name":"Beth
75
+ Wood","address":[{"line1":"NC Office of the State Auditor 20601 Mail Service
76
+ Center","city":"raleigh","state":"NC","zip":"27699"}],"phones":["(919) 807-7526"],"urls":["http://www.ncauditor.net/pub4/Default.aspx"],"emails":["Beth_Wood@ncauditor.net"]},"P11":{"name":"Janet
77
+ Cowell","address":[{"line1":"Department of State Treasurer","line2":"325 n.
78
+ salisbury street","city":"raleigh","state":"NC","zip":"27603"}],"phones":["(919)
79
+ 508-5176"],"urls":["https://www.nctreasurer.com/Pages/default.aspx"],"channels":[{"type":"Facebook","id":"NCDST"}]},"P12":{"name":"Roy
80
+ Cooper","address":[{"line1":"9001 Mail Service Center","city":"raleigh","state":"NC","zip":"27699"}],"phones":["(919)
81
+ 716-6400"],"urls":["http://www.ncdoj.gov/"],"channels":[{"type":"Facebook","id":"157759274279900"},{"type":"Twitter","id":"NCAGO"}]},"P13":{"name":"Elaine
82
+ Marshall","address":[{"line1":"NC Secretary of State PO Box 29622","city":"raleigh","state":"NC","zip":"27626"}],"phones":["(919)
83
+ 807-2000"],"urls":["http://www.sosnc.com/"]},"P14":{"name":"Dan Forest","address":[{"line1":"20401
84
+ Mail Service Center","city":"raleigh","state":"NC","zip":"27699"}],"party":"Republican","phones":["(919)
85
+ 733-7350"],"urls":["http://www.ltgov.state.nc.us/"],"emails":["lt.gov@nc.gov"],"channels":[{"type":"Facebook","id":"DanForestNC"},{"type":"Twitter","id":"DanForestNC"}]},"P15":{"name":"Kay
86
+ R. Hagan","address":[{"line1":"521 Dirksen Senate Office Building","city":"washington","state":"DC","zip":"20510"}],"party":"Democratic","phones":["(202)
87
+ 224-6342"],"urls":["http://www.hagan.senate.gov/"],"photoUrl":"http://www.senate.gov/general/resources/graphic/medium/Hagan_200.jpg","emails":["Senator_Hagan@hagan.senate.gov"],"channels":[{"type":"Facebook","id":"SenatorHagan"},{"type":"Twitter","id":"SenatorHagan"},{"type":"YouTube","id":"SenatorHagan"}]},"P16":{"name":"Richard
88
+ Burr","address":[{"line1":"217 Russell Senate Office Building","city":"washington","state":"DC","zip":"20510"}],"party":"Republican","phones":["(202)
89
+ 224-3154"],"urls":["http://www.burr.senate.gov/public/"],"photoUrl":"http://bioguide.congress.gov/bioguide/photo/B/B001135.jpg","channels":[{"type":"Facebook","id":"SenatorRichardBurr"},{"type":"Twitter","id":"senatorburr"},{"type":"YouTube","id":"SenatorRichardBurr"}]},"P17":{"name":"Cherie
90
+ Berry","address":[{"line1":"NC Department of Labor 1101 Mail Service Center","city":"raleigh","state":"NC","zip":"27699"}],"phones":["(919)
91
+ 807-2796"],"urls":["http://www.nclabor.com/"],"emails":["Commissioners.Office@labor.nc.gov"]},"P18":{"name":"Wayne
92
+ Goodwin","urls":["http://www.ncdoi.com/"],"emails":["Commissioner@ncdoi.gov"],"channels":[{"type":"Facebook","id":"ncdoi"},{"type":"Twitter","id":"NCInsuranceDept"}]},"P19":{"name":"Steve
93
+ Troxler","address":[{"line1":"1001 Mail Service Center","city":"raleigh","state":"NC","zip":"27699"}],"phones":["(919)
94
+ 707-3021"],"urls":["http://www.ncagr.gov/"]},"P20":{"name":"June Atkinson","address":[{"line1":"Office
95
+ of the State Superintendent NC Education Building 6301 Mail Service Center","city":"raleigh","state":"NC","zip":"27699"}],"phones":["(919)
96
+ 807-3430"],"urls":["http://www.ncpublicschools.org/statesuperintendent/"],"emails":["june.atkinson@dpi.nc.gov"]},"P21":{"name":"G.K.
97
+ Butterfield","address":[{"line1":"2305 Rayburn HOB","city":"washington","state":"DC","zip":"20515"}],"party":"Democratic","phones":["(202)
98
+ 225-3101"],"urls":["http://butterfield.house.gov/"],"photoUrl":"http://butterfield.house.gov/images/user_images/GKB_Official_Photo.JPG","channels":[{"type":"Facebook","id":"congressmangkbutterfield"},{"type":"Twitter","id":"gkbutterfield"},{"type":"YouTube","id":"GKBNC01"}]},"P22":{"name":"Barack
99
+ Hussein Obama II","address":[{"line1":"The White House","line2":"1600 Pennsylvania
100
+ Avenue NW","line3":"","city":"Washington","state":"DC","zip":"20500"}],"party":"Democrat","phones":["(202)
101
+ 456-1111","(202) 456-1414"],"urls":["http://www.whitehouse.gov/administration/president_obama/","http://www.barackobama.com/index.php"],"photoUrl":"http://www.whitehouse.gov/sites/default/files/imagecache/admin_official_lowres/administration-official/ao_image/president_official_portrait_hires.jpg","channels":[{"type":"GooglePlus","id":"110031535020051778989"},{"type":"YouTube","id":"barackobama"},{"type":"Twitter","id":"barackobama"},{"type":"Facebook","id":"barackobama"}]},"P23":{"name":"Joseph
102
+ (Joe) Robinette Biden Jr.","address":[{"line1":"The White House","line2":"1600
103
+ Pennsylvania Avenue NW","line3":"","city":"Washington","state":"DC","zip":"20500"}],"party":"Democrat","urls":["http://www.whitehouse.gov/administration/vice-president-biden"],"photoUrl":"http://www.whitehouse.gov/sites/default/files/imagecache/admin_official_lowres/administration-official/ao_image/vp_portrait.jpeg","channels":[{"type":"Twitter","id":"JoeBiden"},{"type":"Facebook","id":"joebiden"},{"type":"Twitter","id":"VP"}]}}}'
104
+ http_version:
105
+ recorded_at: Sat, 28 Dec 2013 06:45:05 GMT
106
+ recorded_with: VCR 2.5.0