civic_aide 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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