13 |
--------------------------------------------------------------------------------
/app/views/devise/sessions/new.html.erb:
--------------------------------------------------------------------------------
1 |
4 |
5 | <%= simple_form_for(resource, as: resource_name, url: session_path(resource_name), html: {id: 'new_session'}) do |f| %>
6 |
7 |
17 |
18 |
19 | <%= f.input :remember_me, as: :hidden, input_html: {value: 1} %>
20 | <%= f.button :submit, 'Sign in', :class => 'cta-pill' %>
21 | <%= render 'devise/shared/links' %>
22 |
23 |
24 | <% end %>
25 |
--------------------------------------------------------------------------------
/app/views/devise/shared/_links.erb:
--------------------------------------------------------------------------------
1 |
2 | <% if controller_name != 'sessions' %>
3 |
4 | <%= link_to 'Sign in', new_session_path(resource_name) %>
5 |
6 | <% end %>
7 | <% if devise_mapping.registerable? && controller_name != 'registrations' %>
8 |
9 | <%= link_to 'Sign up', new_registration_path(resource_name) %>
10 |
11 | <% end %>
12 | <% if devise_mapping.recoverable? && controller_name != 'passwords' %>
13 |
14 | <%= link_to 'Forgot your password?', new_password_path(resource_name) %>
15 |
16 | <% end %>
17 | <% if devise_mapping.omniauthable? %>
18 |
19 | <% resource_class.omniauth_providers.each do |provider| %>
20 | <%= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider) %>
21 | <% end %>
22 |
23 | <% end %>
24 |
--------------------------------------------------------------------------------
/app/views/identity_mailer/identity_needs_inspection.text.erb:
--------------------------------------------------------------------------------
1 | <%= @user.given_name -%> <%= @user.family_name -%> identity needs inspection.
2 |
3 | You can review details and verify or reject the identity here:
4 |
5 | <%= user_url(@user) -%>
6 |
7 | Thank you,
8 | The AskThem Team
--------------------------------------------------------------------------------
/app/views/identity_mailer/identity_rejected.text.erb:
--------------------------------------------------------------------------------
1 | Thank you for requesting your account for verification by AskThem, <%= @user.given_name %>
2 |
3 | Unfortunately we could not verify your identity at this time.
4 |
5 | Thank you,
6 | The AskThem Team
--------------------------------------------------------------------------------
/app/views/identity_mailer/identity_submitted.text.erb:
--------------------------------------------------------------------------------
1 | Thank you for requesting your account for verification by AskThem, <%= @user.given_name %>
2 |
3 | An AskThem staff member will review your request and get back to you.
4 |
5 | Thank you,
6 | The AskThem Team
--------------------------------------------------------------------------------
/app/views/identity_mailer/identity_verified.text.erb:
--------------------------------------------------------------------------------
1 | Thank you for requesting your account for verification by AskThem, <%= @user.given_name %>
2 |
3 | An AskThem staff member has verified your identity. You can now answer questions from the following URL:
4 |
5 | <%= person_url(@person.state, @person.id) -%>
6 |
7 | Thank you,
8 | The AskThem Team
--------------------------------------------------------------------------------
/app/views/kaminari/_first_page.html.erb:
--------------------------------------------------------------------------------
1 | <%# Link to the "First" page
2 | - available local variables
3 | url: url to the first page
4 | current_page: a page object for the currently displayed page
5 | total_pages: total number of pages
6 | per_page: number of items to fetch per page
7 | remote: data-remote
8 | -%>
9 |
--------------------------------------------------------------------------------
/app/views/kaminari/_gap.html.erb:
--------------------------------------------------------------------------------
1 | <%# Non-link tag that stands for skipped pages...
2 | - available local variables
3 | current_page: a page object for the currently displayed page
4 | total_pages: total number of pages
5 | per_page: number of items to fetch per page
6 | remote: data-remote
7 | -%>
8 | <%= raw(t 'views.pagination.truncate') %>
9 |
--------------------------------------------------------------------------------
/app/views/kaminari/_last_page.html.erb:
--------------------------------------------------------------------------------
1 | <%# Link to the "Last" page
2 | - available local variables
3 | url: url to the last page
4 | current_page: a page object for the currently displayed page
5 | total_pages: total number of pages
6 | per_page: number of items to fetch per page
7 | remote: data-remote
8 | -%>
9 |
--------------------------------------------------------------------------------
/app/views/kaminari/_next_page.html.erb:
--------------------------------------------------------------------------------
1 | <%# Link to the "Next" page
2 | - available local variables
3 | url: url to the next page
4 | current_page: a page object for the currently displayed page
5 | total_pages: total number of pages
6 | per_page: number of items to fetch per page
7 | remote: data-remote
8 | -%>
9 |
10 | <%= link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, {
11 | 'rel' => 'next',
12 | 'remote' => remote,
13 | 'data-title' => title(page: current_page + 1),
14 | } %>
15 |
16 |
--------------------------------------------------------------------------------
/app/views/kaminari/_page.html.erb:
--------------------------------------------------------------------------------
1 | <%# Link showing page number
2 | - available local variables
3 | page: a page object for "this" page
4 | url: url to this page
5 | current_page: a page object for the currently displayed page
6 | total_pages: total number of pages
7 | per_page: number of items to fetch per page
8 | remote: data-remote
9 | -%>
10 |
11 | <%= link_to_unless page.current?, page, url, {
12 | 'remote' => remote,
13 | 'rel' => page.next? ? 'next' : page.prev? ? 'prev' : nil,
14 | 'data-title' => title(page: page.number),
15 | } %>
16 |
17 |
--------------------------------------------------------------------------------
/app/views/kaminari/_paginator.html.erb:
--------------------------------------------------------------------------------
1 | <%# The container tag
2 | - available local variables
3 | current_page: a page object for the currently displayed page
4 | total_pages: total number of pages
5 | per_page: number of items to fetch per page
6 | remote: data-remote
7 | paginator: the paginator that renders the pagination tags inside
8 | -%>
9 | <%= paginator.render do -%>
10 |
23 | <% end -%>
24 |
--------------------------------------------------------------------------------
/app/views/kaminari/_prev_page.html.erb:
--------------------------------------------------------------------------------
1 | <%# Link to the "Previous" page
2 | - available local variables
3 | url: url to the previous page
4 | current_page: a page object for the currently displayed page
5 | total_pages: total number of pages
6 | per_page: number of items to fetch per page
7 | remote: data-remote
8 | -%>
9 |
10 | <%= link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, {
11 | 'rel' => 'prev',
12 | 'remote' => remote,
13 | 'data-title' => title(page: current_page - 1),
14 | } %>
15 |
16 |
--------------------------------------------------------------------------------
/app/views/key_votes/_key_vote.html.erb:
--------------------------------------------------------------------------------
1 |
2 | @todo KeyVote
3 |
--------------------------------------------------------------------------------
/app/views/layouts/maintenance.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Maintenance
5 |
35 |
36 |
37 |
38 |
Maintenance
39 |
The system is down for <%= reason ? reason : "maintenance" %> as of <%= Time.now.strftime("%H:%M %Z") %>.
40 |
It'll be back <%= deadline ? deadline : "shortly" %>.
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/views/meetings/_meeting.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | " pubdate>
5 | <%= meeting.date_and_time.strftime "%b %e %Y" %>
6 | <%= meeting.date_and_time.strftime "%l:%M%P" %>
7 |
8 |
9 |
10 |
<%= meeting.name %>
11 |
12 | <% if meeting.agenda %>
13 | <%= link_to 'Download', meeting.agenda.url, class: 'meeting-agenda-download' %>
14 | <% else %>
15 | -
16 | <% end %>
17 |
18 |
19 | <% if meeting.minutes_document %>
20 | <%= link_to 'Minutes', meeting.minutes_document.url %>
21 | <% else %>
22 | -
23 | <% end %>
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/views/pages/_bills.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= render @bills %>
4 |
5 |
6 | <%= paginate @bills, outer_window: 1, params: {format: nil}, replace: '#page', scroll: '.nav_extras' %>
7 |
8 |
--------------------------------------------------------------------------------
/app/views/pages/_key_votes.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= render @key_votes %>
4 |
5 |
6 | <%= paginate @key_votes, outer_window: 1, params: {format: nil}, replace: '#page', scroll: '.nav_extras' %>
7 |
8 |
--------------------------------------------------------------------------------
/app/views/pages/_lower.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= render @lower %>
4 |
5 |
6 | <%= paginate @lower, outer_window: 1, params: {format: nil}, replace: '#page', scroll: '.nav_extras' %>
7 |
8 |
--------------------------------------------------------------------------------
/app/views/pages/_meetings.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <% if @meetings.length > 0 %>
3 |
4 |
5 |
6 |
Name
7 | Agenda
8 | Minutes
9 |
10 | <%= render @meetings %>
11 |
12 | <%= paginate @meetings, outer_window: 1, params: {format: nil}, replace: '#page', scroll: '.nav_extras' %>
13 | <% else %>
14 |
No meetings found
15 | <% end %>
16 |
17 |
--------------------------------------------------------------------------------
/app/views/pages/_people_for_location.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Federal
5 |
6 |
7 |
8 | State
9 |
10 |
11 | <% if municipal_people && municipal_people.count > 0 -%>
12 |
13 | <%= municipality -%>
14 |
15 |
16 | <% end -%>
17 |
18 |
19 |
20 |
21 | <%= render federal_people if federal_people %>
22 |
23 |
24 | <%= render governor if governor %>
25 | <%= render state_people if state_people %>
26 |
27 |
28 | <%# render mayor if mayor %>
29 | <%= render municipal_people if municipal_people %>
30 |
31 |
--------------------------------------------------------------------------------
/app/views/pages/_upper.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%# spell out arguments for subclasses of Person sake -%>
4 | <%= render partial: 'people/person', collection: @upper %>
5 |
6 |
7 | <%= paginate @upper, outer_window: 1, params: {format: nil}, replace: '#page', scroll: '.nav_extras' %>
8 |
9 |
--------------------------------------------------------------------------------
/app/views/pages/channel.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/views/pages/contact_info.csv.erb:
--------------------------------------------------------------------------------
1 | <%- headers = ["Jurisdiction", "Id", "Name", "Title and Details", "Email", "Phone", "Office Details", "Twitter", "Facebook", "Youtube", "Links"] -%>
2 | <%= CSV.generate_line headers %>
3 | <%- @people.each do |person| -%>
4 | <%- row = [person.metadatum.abbreviation,
5 | person.id,
6 | person.full_name,
7 | person_attributes(person, " - "),
8 | person.email.present? ? person.email : nil,
9 | person.read_attribute(:phone),
10 | csv_safe_office_details_for(person),
11 | person.read_attribute(:twitter_id),
12 | person.read_attribute(:facebook_id),
13 | person.read_attribute(:youtube_id),
14 | csv_safe_links_for(person)] -%>
15 | <%= CSV.generate_line row %>
16 | <%- end -%>
17 |
--------------------------------------------------------------------------------
/app/views/pages/elected_signup.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/views/pages/honestads.html.erb:
--------------------------------------------------------------------------------
1 |
2 | HonestAds and AskThem
3 |
20 |
21 |
--------------------------------------------------------------------------------
/app/views/pages/overview.js.erb:
--------------------------------------------------------------------------------
1 | <%= j render(@tab) %>
--------------------------------------------------------------------------------
/app/views/pages/search.html.erb:
--------------------------------------------------------------------------------
1 |
2 | @todo: Bill, etc. search results
3 |
--------------------------------------------------------------------------------
/app/views/pages/widget_builder.html.erb:
--------------------------------------------------------------------------------
1 |
2 | AskThem Widget Builder
3 |
9 |
10 | Note - advanced users can override the built-in styles of the widgets. If you have the know how, go for it!
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/views/people/_bills.html.erb:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/app/views/people/_committees.html.erb:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/app/views/people/_questions.html.erb:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/app/views/people/_ratings.html.erb:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/app/views/people/_votes.html.erb:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/app/views/person_mailer/notify_staff_bad_person.text.erb:
--------------------------------------------------------------------------------
1 | Bad Person - There's something wrong with <%= @cached_official.full_name -%>
2 |
3 | We couldn't find a person that matches these details:
4 |
5 |
6 | <%= @cached_official.attributes %>
7 |
8 |
9 | Typical causes for non-match are use of a nickname or middle name rather than the official name we have for the official.
10 |
11 | If you have a link to who, in our data, should match this person, please pass it on to a developer so they can manually match this person.
12 |
13 | Thank you,
14 | The AskThem Team
15 |
--------------------------------------------------------------------------------
/app/views/person_mailer/notify_staff_new_from_twitter.text.erb:
--------------------------------------------------------------------------------
1 | A person has been added to AskThem with the Twitter screen name <%= @screen_name %>.
2 |
3 | If no one has asked this person a question in 24 hours, they will be automatically deleted from the site.
4 |
5 | Here's a permalink to that person: <%= person_url(@person.state, @person.id) %>
6 |
7 | Thank you,
8 | The AskThem Team
9 |
--------------------------------------------------------------------------------
/app/views/question_mailer/answered_for_author.text.erb:
--------------------------------------------------------------------------------
1 | Hi <%= @user.given_name -%>!
2 |
3 | Exciting News! We wanted to let you know that <%= @question.person.name -%> has replied to the question you submitted:
4 |
5 | <%= @question.title %>
6 |
7 | <%= question_url(@question.state, @question.id) %>
8 |
9 | Click above for the full response!
10 |
11 | Congratulations on the success of your question! We'll notify everyone that signed on and share your question-and-answer on our social media channels.
12 |
13 | Forward this email to friends or click on the question above and share on Facebook.
14 |
15 | Thank you,
16 | The AskThem Team
17 |
--------------------------------------------------------------------------------
/app/views/question_mailer/answered_for_signer.text.erb:
--------------------------------------------------------------------------------
1 | Hi <%= @user.given_name -%>!
2 |
3 | Exciting news- we've received an answer to the question for <%= @question.person.name -%>:
4 |
5 | <%= @question.title %>
6 |
7 | <%= question_url(@question.state, @question.id) %>
8 |
9 | Click above for the full response!
10 |
11 | Thanks for signing on!
12 |
13 | Forward this email to friends or click on the question above and share on Facebook.
14 |
15 | Thank you,
16 | The AskThem Team
17 |
--------------------------------------------------------------------------------
/app/views/question_mailer/email_person.text.erb:
--------------------------------------------------------------------------------
1 | A question asked of you by people on AskThem has reached <%= @question.signature_count %> signatures.
2 |
3 | Title
4 | <%= @question.title %>
5 |
6 | Topic
7 | <%= @question.subject %>
8 |
9 | Body
10 | <%= @question.body %>
11 |
12 | Here's a permalink to that question: <%= question_url(@question.state, @question.id) %>
13 |
14 | Thank you,
15 | The AskThem.io Team
16 |
--------------------------------------------------------------------------------
/app/views/question_mailer/notify_staff_members_answered.text.erb:
--------------------------------------------------------------------------------
1 | Hi,
2 |
3 | A question to <%= @question.person.name -%> has been answered.
4 |
5 | <%= @question.title %>
6 |
7 | <%= question_url(@question.state, @question.id) %>
8 |
9 | Thank you,
10 | The AskThem Team
11 |
--------------------------------------------------------------------------------
/app/views/question_mailer/notify_staff_question_at_threshold.text.erb:
--------------------------------------------------------------------------------
1 | A question has reached its delivery goal of <%= @question.signature_count %> signatures.
2 |
3 | Title
4 | <%= @question.title %>
5 |
6 | Topic
7 | <%= @question.subject %>
8 |
9 | Body
10 | <%= @question.body %>
11 |
12 | Here's a permalink to that question: <%= question_url(@question.state, @question.id) %>
13 |
14 | Thank you,
15 | The AskThem Team
16 |
--------------------------------------------------------------------------------
/app/views/questions/_media.html.erb:
--------------------------------------------------------------------------------
1 | <%- if question.media_file_url.present? %>
2 | <%= question.media_file_url_html %>
3 | <%- end %>
4 | <%- if question.media.url.present? %>
5 | <%- if is_image?(question.media.url) %>
6 | <%= cdn_image_tag(question.media.url, class: "question-image") %>
7 | <%- else %>
8 |
9 | <%= cdn_video_tag(question.media.url, class: "question-video", controls: true) %>
10 | <%- end %>
11 | <%- end %>
12 |
--------------------------------------------------------------------------------
/app/views/questions/_page.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <% if @questions.any? -%>
3 |
4 | <%= render @questions %>
5 |
6 | <%= paginate @questions, outer_window: 1, params: { format: nil }, replace: "#page", scroll: "section" %>
7 | <% elsif !%w(need_answers have_answers need_signatures).include?(params[:action]) %>
8 |
9 |
Nobody has asked any questions yet!
10 |
Do you want to get the ball rolling?
11 | <%= link_to "Ask a Question", new_question_path(@jurisdiction.abbreviation), class: "cta-pill" %>
12 |
13 | <% end -%>
14 |
15 |
--------------------------------------------------------------------------------
/app/views/questions/edit.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= form_for @question, url: question_path(@state_code, @question), validate: true, html: { accept_charset: "utf-8" } do |f| %>
3 | <% @question.errors.full_messages.each do |message| -%>
4 | <%= message -%>
5 | <% end -%>
6 |
7 | <% locals = { jurisdiction: @jurisdiction, question: @question, person: @person, bill: @bill, relevant_steps: @relevant_steps, f: f } -%>
8 |
9 | <%= render partial: "content_step", locals: locals.merge({ step: "content" }) %>
10 |
11 | <%= f.submit "Update", class: "cta-pill" %>
12 | <% end %>
13 |
14 |
--------------------------------------------------------------------------------
/app/views/ratings/_rating.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= rating.sentence(@person, @jurisdiction) %>
3 |
4 |
--------------------------------------------------------------------------------
/app/views/robots/show.text.erb:
--------------------------------------------------------------------------------
1 | User-Agent: *
2 | <%- @disallows.each do |disallow| %>
3 | Disallow: <%= disallow %>
4 | <%- end %>
5 |
--------------------------------------------------------------------------------
/app/views/shared/_accept_terms.html.erb:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/app/views/shared/_banner.html.erb:
--------------------------------------------------------------------------------
1 | <%- if ENV["BANNER_HTML"].present? && session[:banner_viewed].blank? -%>
2 |
10 | <% session[:banner_viewed] = true %>
11 | <%- end %>
12 |
--------------------------------------------------------------------------------
/app/views/shared/_chartbeat.html.erb:
--------------------------------------------------------------------------------
1 | <% if Rails.env.production? && ENV["CHARTBEAT_HOSTNAME"].present? -%>
2 |
18 | <% end -%>
19 |
--------------------------------------------------------------------------------
/app/views/shared/_facebook_connect.html.erb:
--------------------------------------------------------------------------------
1 | <%- if ENV["FACEBOOK_APP_ID"].present? -%>
2 |
21 | <%- end %>
22 |
--------------------------------------------------------------------------------
/app/views/shared/_google_analytics.html.erb:
--------------------------------------------------------------------------------
1 | <% if Rails.env.production? && ENV["GOOGLE_ANALYTICS_APP_ID"].present? -%>
2 |
12 | <% end -%>
13 |
--------------------------------------------------------------------------------
/app/views/shared/_no_questions.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
Ask one of the first questions in your area!
3 | <%= generic_ask_question "Ask your own Question", class: "cta-pill" %>
4 |
5 |
--------------------------------------------------------------------------------
/app/views/shared/_optimizely.html.erb:
--------------------------------------------------------------------------------
1 | <%- if Rails.env.production? && ENV["OPTIMIZELY_FILENAME"].present? -%>
2 |
3 | <%- end %>
4 |
--------------------------------------------------------------------------------
/app/views/shared/_partner_return_to.html.erb:
--------------------------------------------------------------------------------
1 | <%- info = session[:referring_partner_info] %>
2 | <%- if info && info[:name].present? %>
3 | <%- target_url = info[:return_url] || info[:url] %>
4 | <%- link_content = info[:name] %>
5 | <%- if info[:logo] %>
6 | <%- link_content = raw(" ") %>
7 | <%- end %>
8 |
9 |
12 | <%- end %>
13 |
--------------------------------------------------------------------------------
/app/views/shared/_user.html.erb:
--------------------------------------------------------------------------------
1 | <% if user_signed_in? %>
2 | <%= link_to "My Questions", user_path(current_user) %>
3 | <%= link_to "Settings", edit_user_registration_path %>
4 | <%= link_to "Sign out", destroy_user_session_path %>
5 | <% if false %>
6 |
7 | <%= link_to "#" do %><%# @todo ST make dropdown appear %>
8 | <%= current_user.alternate_name %>
9 | <% end %>
10 |
11 | <% end %>
12 | <% else %>
13 | <%= link_to "Sign up", new_user_registration_path %>
14 | <%= link_to "Login", new_user_session_path %>
15 | <%= link_to("Login with Facebook",
16 | user_omniauth_authorize_url(:facebook,
17 | protocol: Rails.env.production? ? "https://" : "http://"),
18 | class: "facebook-login") -%>
19 | <% end %>
20 |
--------------------------------------------------------------------------------
/app/views/signatures/_as_signer.html.erb:
--------------------------------------------------------------------------------
1 | <%- signature, signer = as_signer, as_signer.user %>
2 |
3 |
4 | <%= link_to signers_description(signer), signer %>
5 | <%= distance_of_time_in_words_to_now(signature.created_at) %> ago
6 |
7 |
--------------------------------------------------------------------------------
/app/views/signatures/index.csv.erb:
--------------------------------------------------------------------------------
1 | <%- headers = ["First Name", "Last Name", "Email", "Zipcode"] -%>
2 | <%= CSV.generate_line headers -%>
3 | <%- @signers.each do |user| -%>
4 | <%- row = [user.given_name, user.family_name, user.email, user.postal_code] -%>
5 | <%= CSV.generate_line row -%>
6 | <%- end -%>
7 |
--------------------------------------------------------------------------------
/app/views/subjects/_page.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= render @bills %>
4 |
5 |
6 | <%= paginate @bills, outer_window: 1, params: {format: nil}, replace: '#page', scroll: 'section' %>
7 |
8 |
--------------------------------------------------------------------------------
/app/views/subjects/index.html.erb:
--------------------------------------------------------------------------------
1 | <%= render 'shared/navigation' %>
2 |
3 |
4 |
7 |
8 |
9 | <% @subjects.each do |subject| %>
10 |
11 | <%= link_to subject, subject_path(@jurisdiction.abbreviation, subject.parameterize) %>
12 |
13 | <% end %>
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/views/subjects/show.html.erb:
--------------------------------------------------------------------------------
1 | <%= render 'shared/navigation' %>
2 |
3 |
4 |
7 |
8 | <%= render partial: 'page' %>
9 |
10 |
--------------------------------------------------------------------------------
/app/views/unknown/_unknown.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= image_tag('placeholder.png', size: '60x60', alt: '') %>
4 |
5 |
6 |
<%= unknown.name %>
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/views/users/_questions.html.erb:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/app/views/users/_signatures.html.erb:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/app/views/votes/_vote.html.erb:
--------------------------------------------------------------------------------
1 |
2 | @todo https://github.com/sunlightlabs/billy/wiki/Votes-fields
3 |
4 |
--------------------------------------------------------------------------------
/app/workers/geocode_worker.rb:
--------------------------------------------------------------------------------
1 | class GeocodeWorker
2 | include Sidekiq::Worker
3 |
4 | def perform(id, class_name = "User")
5 | object = class_name.constantize.find(id)
6 | object.geocode
7 | object.save! if object.changed?
8 | rescue Mongoid::Errors::DocumentNotFound
9 | logger.info "#{class_name} : #{id} appears to have been deleted"
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/app/workers/person_check_photo_url_worker.rb:
--------------------------------------------------------------------------------
1 | class PersonCheckPhotoUrlWorker
2 | include Sidekiq::Worker
3 |
4 | attr_accessor :person
5 |
6 | def perform(id)
7 | self.person = Person.find(id.to_s)
8 | return unless person.photo_url.present?
9 |
10 | unless ImageLinkChecker.new(person.photo_url).accessible?
11 | person.archive_photo_url
12 | end
13 |
14 | rescue Mongoid::Errors::DocumentNotFound
15 | logger.info "Person: #{id} appears to have been deleted"
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/app/workers/question_answered_notifier_worker.rb:
--------------------------------------------------------------------------------
1 | class QuestionAnsweredNotifierWorker
2 | include Sidekiq::Worker
3 |
4 | attr_accessor :question
5 |
6 | def perform(id)
7 | self.question = Question.find(id)
8 | return unless question.answered?
9 |
10 | notify_everyone_interested
11 | rescue Mongoid::Errors::DocumentNotFound
12 | logger.info "Question: #{id} appears to have been deleted"
13 | end
14 |
15 | private
16 | def notify_everyone_interested
17 | # QuestionMailer.answered_for_author(question.user, question).deliver
18 |
19 | # question.signatures.collect(&:user).each do |user|
20 | # unless user = question.user
21 | # QuestionMailer.answered_for_signer(user, question).deliver
22 | # end
23 | # end
24 |
25 | QuestionMailer.notify_staff_members_answered(question).deliver
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/app/workers/question_coordinates_worker.rb:
--------------------------------------------------------------------------------
1 | class QuestionCoordinatesWorker
2 | include Sidekiq::Worker
3 |
4 | # user may not have coordinates yet, try until they do
5 | def perform(id)
6 | question = Question.find(id)
7 | user = question.user
8 |
9 | if user && question.coordinates.blank?
10 | if user.coordinates.present?
11 | question.coordinates = user.coordinates
12 | question.save!
13 | else
14 | self.class.perform_in(10.minutes, id)
15 | end
16 | end
17 |
18 | rescue Mongoid::Errors::DocumentNotFound
19 | logger.info "Question: #{id} appears to have been deleted"
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/app/workers/unaffiliated_person_tidy_worker.rb:
--------------------------------------------------------------------------------
1 | class UnaffiliatedPersonTidyWorker
2 | include Sidekiq::Worker
3 |
4 | # tidy up unaffiliated people that don't have questions
5 | # meant to be scheduled at a given period after they are created
6 | def perform(id)
7 | person = Person.find(id)
8 | return if person.questions.any? ||
9 | person.state != Metadatum::Unaffiliated::ABBREVIATION
10 |
11 | person.person_detail.destroy
12 | person.destroy
13 |
14 | rescue Mongoid::Errors::DocumentNotFound
15 | logger.info "Person: #{id} appears to have been deleted"
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/app/workers/user_set_local_jurisdiction_abbreviation_worker.rb:
--------------------------------------------------------------------------------
1 | class UserSetLocalJurisdictionAbbreviationWorker
2 | include Sidekiq::Worker
3 |
4 | attr_accessor :user
5 |
6 | def perform(id)
7 | user = User.find(id.to_s)
8 | options = set_options_from(user)
9 |
10 | return if options[:state].nil?
11 |
12 | user.local_jurisdiction_abbreviation = JurisdictionId.new(options).id
13 | user.save!
14 |
15 | rescue Mongoid::Errors::DocumentNotFound
16 | logger.info "User: #{id} appears to have been deleted"
17 | end
18 |
19 | private
20 | def set_options_from(user)
21 | state = user.region
22 | municipality = user.locality
23 |
24 | if user.coordinates && (state.blank? || municipality.blank?)
25 | geo = Geocoder.search(user.coordinates.reverse).first
26 | state = geo.state_code
27 | municipality = geo.city
28 | end
29 |
30 | { state: state, municipality: municipality }
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/app/workers/user_set_password_notice_worker.rb:
--------------------------------------------------------------------------------
1 | class UserSetPasswordNoticeWorker
2 | include Sidekiq::Worker
3 |
4 | attr_accessor :user
5 |
6 | def perform(id)
7 | self.user = User.find(id.to_s)
8 |
9 | if user.password_is_placeholder? && !user.email_is_disabled?
10 | notify_or_reschedule
11 | end
12 |
13 | rescue Mongoid::Errors::DocumentNotFound
14 | logger.info "User: #{id} appears to have been deleted"
15 | end
16 |
17 | private
18 | def notify_or_reschedule
19 | if !user.class.devise_modules.include?(:confirmable) || user.confirmed?
20 | user.send_reset_password_instructions
21 | user.password_is_placeholder = false
22 | user.save!
23 | else
24 | self.class.perform_in(60.minutes, user.id.to_s)
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require ::File.expand_path('../config/environment', __FILE__)
4 | run OpenGovernment::Application
5 |
--------------------------------------------------------------------------------
/config/boot.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 |
3 | # Set up gems listed in the Gemfile.
4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
5 |
6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
7 |
--------------------------------------------------------------------------------
/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the rails application
2 | require File.expand_path('../application', __FILE__)
3 |
4 | # Initialize the rails application
5 | OpenGovernment::Application.initialize!
6 |
--------------------------------------------------------------------------------
/config/initializers/airbrake.rb:
--------------------------------------------------------------------------------
1 | if ENV['AIRBRAKE_API_KEY']
2 | Airbrake.configure do |config|
3 | config.api_key = ENV['AIRBRAKE_API_KEY']
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/config/initializers/carrierwave.rb:
--------------------------------------------------------------------------------
1 | CarrierWave.configure do |config|
2 | # To serve uploads in development, we must store files in the "public" directory.
3 | config.root = Rails.root.join(Rails.env.production? ? 'tmp' : 'public')
4 | config.cache_dir = 'uploads'
5 | if Rails.env.production?
6 | config.fog_credentials = {
7 | :provider => 'AWS',
8 | :aws_access_key_id => ENV['AWS_ACCESS_KEY_ID'],
9 | :aws_secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'],
10 | }
11 | config.fog_directory = ENV['AWS_DIRECTORY']
12 | config.asset_host = "//#{ENV['AWS_DIRECTORY']}#{ENV['AWS_HOST_STUB']}"
13 | config.storage = :fog
14 | else
15 | config.storage = :file
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/config/initializers/client_side_validations.rb:
--------------------------------------------------------------------------------
1 | # ClientSideValidations Initializer
2 |
3 | # Uncomment to disable uniqueness validator, possible security issue
4 | # ClientSideValidations::Config.disabled_validators = [:uniqueness]
5 |
6 | # Uncomment to validate number format with current I18n locale
7 | # ClientSideValidations::Config.number_format_with_locale = true
8 |
9 | # Uncomment the following block if you want each input field to have the validation messages attached.
10 | ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
11 | unless html_tag =~ /^#{html_tag}#{instance.error_message.first} }.html_safe
13 | else
14 | %{#{html_tag}
}.html_safe
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/config/initializers/kaminari_config.rb:
--------------------------------------------------------------------------------
1 | Kaminari.configure do |config|
2 | # config.default_per_page = 25
3 | # config.max_per_page = nil
4 | # config.window = 4
5 | config.outer_window = 1
6 | # config.left = 0
7 | # config.right = 0
8 | # config.page_method_name = :page
9 | # config.param_name = :page
10 | end
11 |
--------------------------------------------------------------------------------
/config/initializers/mongoid.rb:
--------------------------------------------------------------------------------
1 | # `Mongoid.override_session` overrides any persistence settings set by the model
2 | # using the `store_in` method. Until the below pull request is merged, we need
3 | # to use `with` calls everywhere.
4 | #
5 | # @see https://github.com/mongoid/mongoid/pull/2909
6 | Mongoid::Document::ClassMethods.class_eval do
7 | # Scopes the collection to the jurisdiction.
8 | #
9 | # @param [String] abbreviation a jurisdiction's abbreviation
10 | def connected_to(abbreviation)
11 | where(state: abbreviation)
12 | end
13 | end
14 |
15 | if Rails.env.development?
16 | module Mongoid
17 | module Factory
18 | old_from_db = instance_method(:from_db)
19 |
20 | define_method(:from_db) do |klass, attributes=nil, criteria_instance_id=nil|
21 | attributes.delete('_type') if klass == Metadatum && attributes['_type'] == 'metadata'
22 | old_from_db.bind(self).call(klass, attributes, criteria_instance_id)
23 | end
24 | end
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/config/initializers/rolify.rb:
--------------------------------------------------------------------------------
1 | # we use UserRole to avoid name collision with person.roles
2 | Rolify.configure("UserRole") do |config|
3 | # By default ORM adapter is ActiveRecord. uncomment to use mongoid
4 | config.use_mongoid
5 |
6 | # Dynamic shortcuts for User class (user.is_admin? like methods). Default is: false
7 | # Enable this feature _after_ running rake db:migrate as it relies on the roles table
8 | # config.use_dynamic_shortcuts
9 | end
10 |
--------------------------------------------------------------------------------
/config/initializers/secret_token.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Your secret key for verifying the integrity of signed cookies.
4 | # If you change this key, all old signed cookies will become invalid!
5 | # Make sure the secret is at least 30 characters and all random,
6 | # no regular words or you'll be exposed to dictionary attacks.
7 | OpenGovernment::Application.config.secret_token = ENV['SECRET_TOKEN'] || '996fb248e768fa841bbbb687951717a0e71d07d7446a3ed4deda69af1a5b1df67af9ac62746cca2ec0e9304ed6c21c707198c739755267a3710cc69a416d067a'
8 |
--------------------------------------------------------------------------------
/config/initializers/session_store.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | OpenGovernment::Application.config.session_store :cookie_store, key: '_opengovernment_session'
4 |
5 | # Use the database for sessions instead of the cookie-based default,
6 | # which shouldn't be used to store highly confidential information
7 | # (create the session table with "rails generate session_migration")
8 | # OpenGovernment::Application.config.session_store :active_record_store
9 |
--------------------------------------------------------------------------------
/config/initializers/sidekiq.rb:
--------------------------------------------------------------------------------
1 | # url set via env var
2 | Sidekiq.configure_server do |config|
3 | config.redis = { namespace: "askthem_queues" }
4 | end
5 |
6 | Sidekiq.configure_client do |config|
7 | config.redis = { namespace: "askthem_queues" }
8 | end
9 |
--------------------------------------------------------------------------------
/config/initializers/wrap_parameters.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 | #
3 | # This file contains settings for ActionController::ParamsWrapper which
4 | # is enabled by default.
5 |
6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7 | ActiveSupport.on_load(:action_controller) do
8 | wrap_parameters format: [:json]
9 | end
10 |
11 |
--------------------------------------------------------------------------------
/config/locales/simple_form.en.yml:
--------------------------------------------------------------------------------
1 | en:
2 | simple_form:
3 | "yes": 'Yes'
4 | "no": 'No'
5 | required:
6 | text: 'required'
7 | mark: '*'
8 | # You can uncomment the line below if you need to overwrite the whole required html.
9 | # When using html, text and mark won't be used.
10 | # html: '* '
11 | error_notification:
12 | default_message: "Please review the problems below:"
13 | # Labels and hints examples
14 | # labels:
15 | # defaults:
16 | # password: 'Password'
17 | # user:
18 | # new:
19 | # email: 'E-mail to sign in.'
20 | # edit:
21 | # email: 'E-mail.'
22 | # hints:
23 | # defaults:
24 | # username: 'User name to sign in.'
25 | # password: 'No special characters, please.'
26 | labels:
27 | user:
28 | given_name: First Name
29 | family_name: Last Name
30 | email: Your Email
31 | street_address: Street Address
32 | locality: City
33 | region: State
34 | postal_code: Zipcode
35 | edit:
36 | password: New Password
37 | hints:
38 | user:
39 | edit:
40 | password: leave blank if you don't want to change it
41 |
--------------------------------------------------------------------------------
/config/unicorn.rb:
--------------------------------------------------------------------------------
1 | worker_processes 3
2 | timeout 30
3 | preload_app true
4 |
5 | # @todo this is only a good set up for staging site on heroku
6 | # revisit when moving to deploying with capistrano
7 | # source: https://coderwall.com/p/fprnhg
8 | before_fork do |server, worker|
9 | @sidekiq_pid ||= spawn("bundle exec sidekiq -q geocoding -c 2")
10 | end
11 |
12 | after_fork do |server, worker|
13 | Sidekiq.configure_client do |config|
14 | config.redis = { :size => 1 }
15 | end
16 |
17 | Sidekiq.configure_server do |config|
18 | config.redis = { :size => 5 }
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/doc/README.md:
--------------------------------------------------------------------------------
1 | `indexes.txt` is output by `mongorestore` when loading the [OpenStates MongoDB dump](http://static.openstates.org.s3.amazonaws.com/mongo/latest-mongo-dump.tar.gz).
2 |
--------------------------------------------------------------------------------
/doc/variety/README.md:
--------------------------------------------------------------------------------
1 | The files in this directory were produced by running, e.g.:
2 |
3 | mongo fiftystates --eval "var collection = 'bills'" script/variety.js
4 |
5 | The results of their analysis are on the [Billy wiki](https://github.com/sunlightlabs/billy/wiki) under "Collections and fields".
6 |
--------------------------------------------------------------------------------
/doc/variety/districts.txt:
--------------------------------------------------------------------------------
1 | { "_id" : { "key" : "_id" }, "value" : { "type" : "String" }, "totalOccurrences" : 6824, "percentContaining" : 100 }
2 | { "_id" : { "key" : "name" }, "value" : { "type" : "String" }, "totalOccurrences" : 6824, "percentContaining" : 100 }
3 | { "_id" : { "key" : "chamber" }, "value" : { "type" : "String" }, "totalOccurrences" : 6824, "percentContaining" : 100 }
4 | { "_id" : { "key" : "abbr" }, "value" : { "type" : "String" }, "totalOccurrences" : 6824, "percentContaining" : 100 }
5 | { "_id" : { "key" : "boundary_id" }, "value" : { "type" : "String" }, "totalOccurrences" : 6824, "percentContaining" : 100 }
6 | { "_id" : { "key" : "num_seats" }, "value" : { "type" : "Number" }, "totalOccurrences" : 6824, "percentContaining" : 100 }
7 |
--------------------------------------------------------------------------------
/doc/variety/subjects.txt:
--------------------------------------------------------------------------------
1 | { "_id" : { "key" : "_id" }, "value" : { "type" : "String" }, "totalOccurrences" : 30792, "percentContaining" : 100 }
2 | { "_id" : { "key" : "remote" }, "value" : { "type" : "String" }, "totalOccurrences" : 30792, "percentContaining" : 100 }
3 | { "_id" : { "key" : "abbr" }, "value" : { "type" : "String" }, "totalOccurrences" : 30792, "percentContaining" : 100 }
4 | { "_id" : { "key" : "normal" }, "value" : { "type" : "Array" }, "totalOccurrences" : 30792, "percentContaining" : 100 }
5 |
--------------------------------------------------------------------------------
/examples/_heroku.rb:
--------------------------------------------------------------------------------
1 | # required environmental variables
2 | #
3 | # Sign up at http://services.sunlightlabs.com/accounts/register/
4 | # ENV["SUNLIGHT_API_KEY"] ||= ""
5 | # ENV["FACEBOOK_APP_SECRET"] ||= ""
6 | # ENV["PROJECT_VOTE_SMART_API_KEY"] ||= ""
7 | # ENV["AWS_DIRECTORY"] ||= ""
8 | # ENV["AWS_HOST_STUB"] ||= ".s3.amazonaws.com"
9 | # ENV["GOOGLE_API_KEY"] ||= ""
10 | # ENV["TWITTER_APPLICATION_CONSUMER_KEY"] ||= ""
11 | # ENV["TWITTER_APPLICATION_CONSUMER_SECRET"] ||= ""
12 | # ENV["TWITTER_APPLICATION_BEARER_TOKEN"] ||= ""
13 | # ENV["DISQUS_SHORTNAME"] ||= ""
14 | # ENV["GOOGLE_ANALYTICS_APP_ID"] ||= ""
15 | # ENV["GOOGLE_ANALYTICS_HOSTNAME"] ||= ""
16 | # ENV["FACEBOOK_ADMINS_ID"] ||= ""
17 | # ENV["FACEBOOK_APP_ID"] ||= ""
18 | # ENV["CHARTBEAT_UID"] ||= ""
19 | # ENV["CHARTBEAT_HOSTNAME"] ||= ""
20 | # ENV["OPTIMIZELY_FILENAME"] ||= ""
21 | # ENV["DESK_COM_SITE"] ||= ""
22 | # ENV["CRM_SUBSCRIBE_ACTION_URL"] ||= ""
23 | # ENV["SPLASH_AS_HOMEPAGE"] ||= ""
24 | # ENV["NOTIFICATION_SENDER_EMAIL"] ||= ""
25 | # ENV["BLITZ_AUTHORIZATION_META"] ||= ""
26 | # ENV["BANNER_HTML"] ||=
27 | # ENV["DEVISE_SECRET_KEY"] ||=
28 |
--------------------------------------------------------------------------------
/lib/democracy_map_governor_adapter.rb:
--------------------------------------------------------------------------------
1 | # Democracy Map governor record handling
2 | class DemocracyMapGovernorAdapter < SimpleDelegator
3 | def run(data)
4 | data.each do |key, value|
5 | case key
6 | when "title"
7 | write_attribute :political_position, value.downcase
8 | when "name_given"
9 | self.first_name = value
10 | when "name_family"
11 | self.last_name = value
12 | when "name_full"
13 | self.full_name = value
14 | when "social_media"
15 | set_social_media(value)
16 | when "url_photo"
17 | self.photo_url = value
18 | else
19 | write_attribute key.to_sym, value
20 | end
21 | end
22 | self.write_attribute :active, true
23 | end
24 |
25 | private
26 | # @todo handle other types
27 | def set_social_media(value)
28 | return unless value
29 |
30 | twitter_id = value.inject("") do |result, hash|
31 | result = hash["username"] if hash["type"] == "twitter"
32 | end
33 |
34 | self.write_attribute(:twitter_id, twitter_id)
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/lib/influence_explorer.rb:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # A simple wrapper for the Influence Explorer API.
3 | class InfluenceExplorer
4 | attr_accessor :api_key
5 |
6 | # @params [Hash] options optional arguments
7 | # @option options [String] :api_key a Influence Explorer API key
8 | def initialize(options = {})
9 | @api_key = options[:api_key] || ENV['SUNLIGHT_API_KEY']
10 | end
11 |
12 | def data_for(id)
13 | JSON.parse(get(id.strip))
14 | end
15 |
16 | private
17 | def base_api_url
18 | 'http://transparencydata.com/api/1.0/entities/'
19 | end
20 |
21 | def get(id)
22 | wait = 1
23 | begin
24 | RestClient.get "#{base_api_url}#{id}.json", params: { apikey: api_key }
25 | rescue Errno::ECONNRESET, RestClient::ServerBrokeConnection
26 | wait *= 2 # exponential backoff
27 | sleep wait
28 | retry
29 | end
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/lib/legislator.rb:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # mixin for legislator functionality
3 | module Legislator
4 | def most_recent_chamber
5 | most_recent :chamber
6 | end
7 |
8 | def most_recent_chamber_title
9 | metadatum.chamber_title most_recent_chamber
10 | end
11 |
12 | def most_recent_district
13 | most_recent :district
14 | end
15 |
16 | def political_position
17 | most_recent_chamber
18 | end
19 |
20 | def political_position_title
21 | most_recent_chamber_title
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/lib/legislator_finder.rb:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # class methods for legislator subclasses of Person
3 | module LegislatorFinder
4 | def for_location(location, api = nil)
5 | api ||= default_api.new
6 | where(:id.in => api.ids_for(LocationFormatter.new(location).format))
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/lib/sunlight_legislator_locator_base.rb:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # mixin for legislator locator functionality
3 | # shared by OpenStates and Congress service classes
4 | module SunlightLegislatorLocatorBase
5 | def ids_for(location)
6 | return [] unless location
7 |
8 | api_parse(results_for_location(location, fields: id_field))
9 | .inject([]) do |ids, result|
10 | ids << result[id_field]
11 | end
12 | end
13 |
14 | def parsed_results_for_jurisdiction(abbreviation, options = {})
15 | params = {
16 | state: format_abbreviation(abbreviation),
17 | apikey: key
18 | }.merge(options)
19 |
20 | api_parse(RestClient.get(legislators_url, params: params))
21 | end
22 |
23 | private
24 | def api_parse(data)
25 | JSON.parse data
26 | end
27 |
28 | def results_for_location(data, options = {})
29 | params = params_for_location(data).merge(options)
30 |
31 | RestClient.get geo_url, params: params
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/lib/tasks/cron.rake:
--------------------------------------------------------------------------------
1 | task cron: :environment do
2 | Rake::Task['openstates:update'].invoke
3 | end
4 |
--------------------------------------------------------------------------------
/lib/tasks/governors.rake:
--------------------------------------------------------------------------------
1 | namespace :governors do
2 | desc "Import governors from DemocracyMap"
3 | task load: :environment do
4 | Governor.load_governors
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/lib/tasks/scraped_local_gov.rake:
--------------------------------------------------------------------------------
1 | namespace :scraped_local_gov do
2 | desc "Import City Council meetings from scraper mongo collection"
3 | task meetings: :environment do
4 | Meeting.load_from_apis_for_jurisdiction
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/lib/templates/erb/scaffold/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%%= simple_form_for(@<%= singular_table_name %>) do |f| %>
2 | <%%= f.error_notification %>
3 |
4 |
5 | <%- attributes.each do |attribute| -%>
6 | <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %>
7 | <%- end -%>
8 |
9 |
10 |
11 | <%%= f.button :submit %>
12 |
13 | <%% end %>
14 |
--------------------------------------------------------------------------------
/lib/twitter_person_adapter.rb:
--------------------------------------------------------------------------------
1 | class TwitterPersonAdapter < SimpleDelegator
2 | def run(twitter_user)
3 | data = twitter_user.as_json
4 |
5 | data.each do |key, value|
6 | case key
7 | when :id, :status
8 | next
9 | when :screen_name
10 | write_attribute :twitter_id, value
11 | when :name
12 | self.full_name = value if value
13 | when :profile_image_url
14 | self.photo_url = value
15 | when :verified
16 | write_attribute :twitter_verified, value
17 | else
18 | write_attribute(key, value) if value
19 | end
20 | self.state = Metadatum::Unaffiliated::ABBREVIATION
21 | end
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/log/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opengovernment/askthem/4f5c2199c4818df929fa6b647b9271dcfbf66793/log/.gitkeep
--------------------------------------------------------------------------------
/public/403.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Forbidden
5 |
6 |
36 |
37 |
38 |
39 |
Access Denied
40 |
You do not have permission to access this resource.
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/public/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The page you were looking for doesn't exist (404)
5 |
35 |
36 |
37 |
38 |
39 |
The page you were looking for doesn't exist.
40 |
You may have mistyped the address or the page may have moved.
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/public/422.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The change you wanted was rejected (422)
5 |
35 |
36 |
37 |
38 |
39 |
The change you wanted was rejected.
40 |
Maybe you tried to change something you didn't have access to.
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/public/500.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | We're sorry, but something went wrong (500)
5 |
35 |
36 |
37 |
38 |
39 |
We're sorry, but something went wrong.
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/apple-touch-icon-120x120-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opengovernment/askthem/4f5c2199c4818df929fa6b647b9271dcfbf66793/public/apple-touch-icon-120x120-precomposed.png
--------------------------------------------------------------------------------
/public/apple-touch-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opengovernment/askthem/4f5c2199c4818df929fa6b647b9271dcfbf66793/public/apple-touch-icon-120x120.png
--------------------------------------------------------------------------------
/public/apple-touch-icon-57x57-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opengovernment/askthem/4f5c2199c4818df929fa6b647b9271dcfbf66793/public/apple-touch-icon-57x57-precomposed.png
--------------------------------------------------------------------------------
/public/apple-touch-icon-57x57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opengovernment/askthem/4f5c2199c4818df929fa6b647b9271dcfbf66793/public/apple-touch-icon-57x57.png
--------------------------------------------------------------------------------
/public/apple-touch-icon-76x76-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opengovernment/askthem/4f5c2199c4818df929fa6b647b9271dcfbf66793/public/apple-touch-icon-76x76-precomposed.png
--------------------------------------------------------------------------------
/public/apple-touch-icon-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opengovernment/askthem/4f5c2199c4818df929fa6b647b9271dcfbf66793/public/apple-touch-icon-76x76.png
--------------------------------------------------------------------------------
/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opengovernment/askthem/4f5c2199c4818df929fa6b647b9271dcfbf66793/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opengovernment/askthem/4f5c2199c4818df929fa6b647b9271dcfbf66793/public/favicon.ico
--------------------------------------------------------------------------------
/public/mark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opengovernment/askthem/4f5c2199c4818df929fa6b647b9271dcfbf66793/public/mark.png
--------------------------------------------------------------------------------
/public/widgets/address/assets/vendor-ba26407e909fb4a64f1f0a2ade32443c.css:
--------------------------------------------------------------------------------
1 | ic-modal,ic-modal-main,ic-modal-screen,ic-modal-title{display:block}.ic-modal-form,ic-modal{display:none;-webkit-overflow-scrolling:touch;position:fixed;bottom:0;left:0;right:0;top:0;overflow:auto;background-color:hsla(0,0%,100%,.9);padding:10px}.ic-modal-form[is-open],ic-modal[is-open]{display:block}ic-modal-main{position:relative;margin:40px auto;max-width:800px;padding:20px;border-radius:4px;background:#fff;border:1px solid #b2b2b2}ic-modal-title{margin:0 -20px 20px;padding:0 20px 20px;border-bottom:1px solid #e5e5e5}.ic-modal-trigger.ic-modal-close{position:absolute;right:10px;top:10px;background:0 0;border:none;color:inherit;font-size:18px;padding:6px}.ic-modal-trigger.ic-modal-close:focus{outline:0;text-shadow:0 0 6px #699cc8,0 0 2px #699cc8,0 0 2px #699cc8,0 0 1px #699cc8}
--------------------------------------------------------------------------------
/public/widgets/person/assets/vendor-ba26407e909fb4a64f1f0a2ade32443c.css:
--------------------------------------------------------------------------------
1 | ic-modal,ic-modal-main,ic-modal-screen,ic-modal-title{display:block}.ic-modal-form,ic-modal{display:none;-webkit-overflow-scrolling:touch;position:fixed;bottom:0;left:0;right:0;top:0;overflow:auto;background-color:hsla(0,0%,100%,.9);padding:10px}.ic-modal-form[is-open],ic-modal[is-open]{display:block}ic-modal-main{position:relative;margin:40px auto;max-width:800px;padding:20px;border-radius:4px;background:#fff;border:1px solid #b2b2b2}ic-modal-title{margin:0 -20px 20px;padding:0 20px 20px;border-bottom:1px solid #e5e5e5}.ic-modal-trigger.ic-modal-close{position:absolute;right:10px;top:10px;background:0 0;border:none;color:inherit;font-size:18px;padding:6px}.ic-modal-trigger.ic-modal-close:focus{outline:0;text-shadow:0 0 6px #699cc8,0 0 2px #699cc8,0 0 2px #699cc8,0 0 1px #699cc8}
--------------------------------------------------------------------------------
/public/widgets/widget-builder/assets/vendor-ba26407e909fb4a64f1f0a2ade32443c.css:
--------------------------------------------------------------------------------
1 | ic-modal,ic-modal-main,ic-modal-screen,ic-modal-title{display:block}.ic-modal-form,ic-modal{display:none;-webkit-overflow-scrolling:touch;position:fixed;bottom:0;left:0;right:0;top:0;overflow:auto;background-color:hsla(0,0%,100%,.9);padding:10px}.ic-modal-form[is-open],ic-modal[is-open]{display:block}ic-modal-main{position:relative;margin:40px auto;max-width:800px;padding:20px;border-radius:4px;background:#fff;border:1px solid #b2b2b2}ic-modal-title{margin:0 -20px 20px;padding:0 20px 20px;border-bottom:1px solid #e5e5e5}.ic-modal-trigger.ic-modal-close{position:absolute;right:10px;top:10px;background:0 0;border:none;color:inherit;font-size:18px;padding:6px}.ic-modal-trigger.ic-modal-close:focus{outline:0;text-shadow:0 0 6px #699cc8,0 0 2px #699cc8,0 0 2px #699cc8,0 0 1px #699cc8}
--------------------------------------------------------------------------------
/public/widgets/zip/ask-little.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opengovernment/askthem/4f5c2199c4818df929fa6b647b9271dcfbf66793/public/widgets/zip/ask-little.png
--------------------------------------------------------------------------------
/public/widgets/zip/honestads2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opengovernment/askthem/4f5c2199c4818df929fa6b647b9271dcfbf66793/public/widgets/zip/honestads2.png
--------------------------------------------------------------------------------
/public/widgets/zip/question-little.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opengovernment/askthem/4f5c2199c4818df929fa6b647b9271dcfbf66793/public/widgets/zip/question-little.png
--------------------------------------------------------------------------------
/script/openstates.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # It is not recommended to use the MongoDB dump in production as it is not
3 | # officially supported and maintained.
4 |
5 | # Remove the previous dump.
6 | rm -rf dump/
7 | rm -rf latest-mongo-dump.tar.gz
8 | # Get a fresh dump.
9 | curl -O http://static.openstates.org.s3.amazonaws.com/mongo/latest-mongo-dump.tar.gz
10 | tar xvf latest-mongo-dump.tar.gz
11 | # Remove unnecessary collections.
12 | rm -f dump/fiftystates/{billy_runs,document_ids,event_ids,manual.leg_ids,manual.name_matchers,popularity_counts,quality_exceptions,reports,tracked_versions,vote_ids}.bson
13 | # Can add --noIndexRestore and use the `billy-util mongo-index --purge` command instead.
14 | mongorestore -drop dump/
15 |
--------------------------------------------------------------------------------
/script/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3 |
4 | APP_PATH = File.expand_path('../../config/application', __FILE__)
5 | require File.expand_path('../../config/boot', __FILE__)
6 | require 'rails/commands'
7 |
--------------------------------------------------------------------------------
/script/sanity/helper.js:
--------------------------------------------------------------------------------
1 | var verbose;
2 |
3 | // Turn off some reports by default.
4 | if (typeof verbose === 'undefined') {
5 | verbose = false;
6 | }
7 |
8 | // Finds documents in the given collection matching the given criteria. If any
9 | // documents are found, prints the given message and, for each document, prints
10 | // its ID and the value of the given field.
11 | var reportList = function (collection, field, criteria, message) {
12 | message = message || collection + ' with invalid ' + field;
13 |
14 | var count = db[collection].count(criteria);
15 | if (count) {
16 | print('\n# ' + message + ':');
17 | db[collection].find(criteria).forEach(function (obj) {
18 | if (field.indexOf('.') === -1) {
19 | print(obj._id + ': ' + obj[field]);
20 | }
21 | else {
22 | print(obj._id);
23 | }
24 | });
25 | }
26 | };
27 |
28 | // Finds documents in the given collection matching the given criteria. If any
29 | // documents are found, prints the number of documents found e.g. "100 bills"
30 | // followed by the given message.
31 | var reportTotal = function (collection, criteria, message) {
32 | var count = db[collection].count(criteria);
33 | if (count) {
34 | print('\n' + count + ' ' + collection + ' ' + message);
35 | }
36 | };
37 |
--------------------------------------------------------------------------------
/script/sanity/manual-review.js:
--------------------------------------------------------------------------------
1 | // Used as part of a poor man's sprintf to align party counts.
2 | var pad = ' ';
3 |
4 | print('\nDistinct parties for manual review:');
5 | db.legislators.mapReduce(function () {
6 | if (this.party) {
7 | emit(this.party, 1);
8 | }
9 | }, function (key, values) {
10 | return Array.sum(values);
11 | }, {out: {inline: 1}}).results.forEach(function (result) {
12 | print(result._id + pad.substring(0, 40 - result._id.length) + result.value);
13 | });
14 |
15 | print('\nDistinct members.roles for manual review:');
16 | db.committees.mapReduce(function () {
17 | this.members.forEach(function (member) {
18 | emit(member.role, 1);
19 | });
20 | }, function (key, values) {
21 | return Array.sum(values);
22 | }, {out: {inline: 1}}).results.forEach(function (result) {
23 | print(result._id + pad.substring(0, 40 - result._id.length) + result.value);
24 | });
25 |
--------------------------------------------------------------------------------
/spec/authorizers/identify_authorizer_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe IdentityAuthorizer do
4 | context "class" do
5 | it "lets anyone create" do
6 | expect(IdentityAuthorizer).to be_creatable_by(User.new)
7 | end
8 | end
9 |
10 | context "instances" do
11 | let(:identity) { FactoryGirl.create(:identity) }
12 |
13 | it "forbids non-staff from updating" do
14 | expect(identity.authorizer).not_to be_updatable_by(identity.user)
15 | end
16 |
17 | it "lets staff members update with results of inspection" do
18 | staff_member = FactoryGirl.create(:user)
19 | staff_member.add_role :staff_member
20 |
21 | expect(identity.authorizer).to be_updatable_by(staff_member)
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/spec/cassettes/ImageLinkChecker/_accessible_/is_false_if_url_s_content_type_is_not_an_image.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: head
5 | uri: http://w3.legis.state.ak.us/images/senate/STGGGGG.jpg
6 | body:
7 | encoding: US-ASCII
8 | string: ''
9 | headers:
10 | User-Agent:
11 | - Ruby Net/HTTP used for link checking mechanism AskThem.io
12 | Accept:
13 | - ! '*/*'
14 | response:
15 | status:
16 | code: 302
17 | message: Found
18 | headers:
19 | Date:
20 | - Wed, 07 May 2014 04:22:41 GMT
21 | Server:
22 | - Apache
23 | Location:
24 | - http://w3.legis.state.ak.us/error/404.php
25 | Content-Type:
26 | - text/html; charset=iso-8859-1
27 | Via:
28 | - 1.1 BC2-ACLD
29 | Connection:
30 | - close
31 | body:
32 | encoding: US-ASCII
33 | string: ''
34 | http_version:
35 | recorded_at: Wed, 07 May 2014 04:22:42 GMT
36 | recorded_with: VCR 2.9.0
37 |
--------------------------------------------------------------------------------
/spec/cassettes/ImageLinkChecker/_accessible_/is_true_if_url_is_available_and_its_content_type_is_an_image.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: head
5 | uri: http://w3.legis.state.ak.us/images/senate/STG.jpg
6 | body:
7 | encoding: US-ASCII
8 | string: ''
9 | headers:
10 | User-Agent:
11 | - Ruby Net/HTTP used for link checking mechanism AskThem.io
12 | Accept:
13 | - ! '*/*'
14 | response:
15 | status:
16 | code: 200
17 | message: OK
18 | headers:
19 | Date:
20 | - Wed, 07 May 2014 04:22:40 GMT
21 | Server:
22 | - Apache
23 | Last-Modified:
24 | - Thu, 10 Oct 2013 00:11:08 GMT
25 | Etag:
26 | - ! '"1ab0d2-8f42-4e857d6b178d8"'
27 | Accept-Ranges:
28 | - bytes
29 | Access-Control-Allow-Origin:
30 | - ! '*'
31 | Content-Type:
32 | - image/jpeg
33 | Via:
34 | - 1.1 BC2-ACLD
35 | Content-Length:
36 | - '36674'
37 | Connection:
38 | - close
39 | body:
40 | encoding: US-ASCII
41 | string: ''
42 | http_version:
43 | recorded_at: Wed, 07 May 2014 04:22:41 GMT
44 | recorded_with: VCR 2.9.0
45 |
--------------------------------------------------------------------------------
/spec/cassettes/PersonCheckPhotoUrlWorker/_perform/when_person_s_photo_url_is_not_available/the_photo_url_is_archived.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: head
5 | uri: http://example.com/example.jpg
6 | body:
7 | encoding: US-ASCII
8 | string: ''
9 | headers:
10 | User-Agent:
11 | - Ruby Net/HTTP used for link checking mechanism AskThem.io
12 | Accept:
13 | - ! '*/*'
14 | response:
15 | status:
16 | code: 404
17 | message: Not Found
18 | headers:
19 | Accept-Ranges:
20 | - bytes
21 | Cache-Control:
22 | - max-age=604800
23 | Content-Type:
24 | - text/html
25 | Date:
26 | - Wed, 07 May 2014 04:31:49 GMT
27 | Etag:
28 | - ! '"359670651"'
29 | Expires:
30 | - Wed, 14 May 2014 04:31:49 GMT
31 | Last-Modified:
32 | - Fri, 09 Aug 2013 23:54:35 GMT
33 | Server:
34 | - ECS (sjc/4E7A)
35 | X-Cache:
36 | - 404-HIT
37 | X-Ec-Custom-Error:
38 | - '1'
39 | Via:
40 | - 1.1 BC1-ACLD
41 | Content-Length:
42 | - '1270'
43 | Connection:
44 | - Keep-Alive
45 | body:
46 | encoding: US-ASCII
47 | string: ''
48 | http_version:
49 | recorded_at: Wed, 07 May 2014 04:31:49 GMT
50 | recorded_with: VCR 2.9.0
51 |
--------------------------------------------------------------------------------
/spec/cassettes/pages_index/Top_Questions_Near/displays_user_s_city.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: get
5 | uri: http://freegeoip.net/json/161.185.30.156
6 | body:
7 | encoding: US-ASCII
8 | string: ''
9 | headers:
10 | Accept-Encoding:
11 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12 | Accept:
13 | - ! '*/*'
14 | User-Agent:
15 | - Ruby
16 | response:
17 | status:
18 | code: 200
19 | message: OK
20 | headers:
21 | Access-Control-Allow-Origin:
22 | - ! '*'
23 | Content-Type:
24 | - application/json
25 | Date:
26 | - Mon, 09 Sep 2013 09:09:39 GMT
27 | Via:
28 | - 1.1 BC4-ACLD
29 | Content-Length:
30 | - '230'
31 | Connection:
32 | - Keep-Alive
33 | Age:
34 | - '0'
35 | body:
36 | encoding: US-ASCII
37 | string: ! '{"ip":"161.185.30.156","country_code":"US","country_name":"United
38 | States","region_code":"NY","region_name":"New York","city":"Brooklyn","zipcode":"11201","latitude":40.6944,"longitude":-73.9906,"metro_code":"501","areacode":"718"}'
39 | http_version:
40 | recorded_at: Mon, 09 Sep 2013 09:09:41 GMT
41 | recorded_with: VCR 2.5.0
42 |
--------------------------------------------------------------------------------
/spec/cassettes/pages_index/Top_Questions_Near/when_there_are_questions_near_the_user/displays_number_of_answers_near_a_user_s_location.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: get
5 | uri: http://freegeoip.net/json/161.185.30.156
6 | body:
7 | encoding: US-ASCII
8 | string: ''
9 | headers:
10 | Accept-Encoding:
11 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12 | Accept:
13 | - ! '*/*'
14 | User-Agent:
15 | - Ruby
16 | response:
17 | status:
18 | code: 200
19 | message: OK
20 | headers:
21 | Access-Control-Allow-Origin:
22 | - ! '*'
23 | Content-Type:
24 | - application/json
25 | Content-Length:
26 | - '230'
27 | Date:
28 | - Wed, 11 Sep 2013 05:43:31 GMT
29 | body:
30 | encoding: US-ASCII
31 | string: ! '{"ip":"161.185.30.156","country_code":"US","country_name":"United
32 | States","region_code":"NY","region_name":"New York","city":"Brooklyn","zipcode":"11201","latitude":40.6944,"longitude":-73.9906,"metro_code":"501","areacode":"718"}'
33 | http_version:
34 | recorded_at: Wed, 11 Sep 2013 05:43:37 GMT
35 | recorded_with: VCR 2.5.0
36 |
--------------------------------------------------------------------------------
/spec/cassettes/pages_index/Top_Questions_Near/when_there_are_questions_near_the_user/displays_number_of_signatures_near_a_user_s_location.yml:
--------------------------------------------------------------------------------
1 | ---
2 | http_interactions:
3 | - request:
4 | method: get
5 | uri: http://freegeoip.net/json/161.185.30.156
6 | body:
7 | encoding: US-ASCII
8 | string: ''
9 | headers:
10 | Accept-Encoding:
11 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12 | Accept:
13 | - ! '*/*'
14 | User-Agent:
15 | - Ruby
16 | response:
17 | status:
18 | code: 200
19 | message: OK
20 | headers:
21 | Access-Control-Allow-Origin:
22 | - ! '*'
23 | Content-Type:
24 | - application/json
25 | Content-Length:
26 | - '230'
27 | Date:
28 | - Wed, 11 Sep 2013 05:43:29 GMT
29 | body:
30 | encoding: US-ASCII
31 | string: ! '{"ip":"161.185.30.156","country_code":"US","country_name":"United
32 | States","region_code":"NY","region_name":"New York","city":"Brooklyn","zipcode":"11201","latitude":40.6944,"longitude":-73.9906,"metro_code":"501","areacode":"718"}'
33 | http_version:
34 | recorded_at: Wed, 11 Sep 2013 05:43:35 GMT
35 | recorded_with: VCR 2.5.0
36 |
--------------------------------------------------------------------------------
/spec/controllers/application_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe ApplicationController do
4 | describe "#staff_member?" do
5 | context "when not a signed in user" do
6 | it "returns false" do
7 | expect(controller.staff_member?).to be_false
8 | end
9 | end
10 |
11 | context "when a signed in user" do
12 | before :each do
13 | @user = FactoryGirl.create(:user)
14 | sign_in @user
15 | end
16 |
17 | it "returns false when does not have staff member role" do
18 | expect(controller.staff_member?).to be_false
19 | end
20 |
21 | context "when user has staff_member role" do
22 | before do
23 | @user.add_role :staff_member
24 | end
25 |
26 | it "returns true" do
27 | expect(controller.staff_member?).to be_true
28 | end
29 | end
30 | end
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/spec/controllers/robots_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe RobotsController do
4 | render_views
5 |
6 | describe "#show" do
7 | it "returns robots.txt file" do
8 | FactoryGirl.create(:metadatum, abbreviation: "vt")
9 |
10 | get :show, format: "txt"
11 | expect(response.body).to have_text question_new_disallow
12 | end
13 |
14 | def question_new_disallow
15 | "Disallow: /vt/questions/new"
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/spec/features/locator_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 | require File.expand_path("../features_helper.rb", __FILE__)
3 |
4 | # see pages_controller_spec for specs that set session variables
5 | describe "pages#locator" do
6 | let(:person) { FactoryGirl.create(:federal_legislator_bernard_sanders) }
7 |
8 | before do
9 | person.write_attribute(:active, true)
10 | person.save!
11 | end
12 |
13 | context "when passed only_show parameter with people as value" do
14 | it "only shows elected officials", vcr: true do
15 | question = FactoryGirl.create(:question,
16 | title: "xyz",
17 | person: person,
18 | state: "vt")
19 |
20 | visit "/locator?q=05602&only_show=people"
21 |
22 | expect(page).to have_content("Bernard Sanders")
23 | expect(page).to_not have_content(question.title)
24 | end
25 |
26 | it "includes a button to ask each person a question", vcr: true do
27 | visit "/locator?q=05602&only_show=people"
28 | expect(page.body.include?("/vt/questions/new?person=S000033")).to be_true
29 | end
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/spec/features/meetings_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 | require File.expand_path("../features_helper.rb", __FILE__)
3 |
4 | describe 'meeting' do
5 |
6 | describe '#index' do
7 |
8 | context 'state jurisdiction' do
9 | it 'returns none' do
10 | Metadatum.create(name: 'Vermont',
11 | abbreviation: 'vt',
12 | chambers: {} )
13 |
14 | visit '/vt'
15 | page.body.should_not have_selector '.meetings-tab'
16 | end
17 | end
18 |
19 | context "local jurisdiction" do
20 | before :each do
21 | Metadatum.create(name: 'Philadelphia',
22 | abbreviation: 'pa-philadelphia',
23 | chambers: {} )
24 | end
25 |
26 | context 'when it has no meetings' do
27 | it 'returns none' do
28 | visit '/pa-philadelphia/overview/meetings'
29 | page.body.should have_content 'No meetings found'
30 | end
31 | end
32 |
33 | context 'when it has meetings' do
34 | it 'returns them' do
35 | FactoryGirl.create(:meeting)
36 | visit '/pa-philadelphia/overview/meetings'
37 | page.body.should have_content 'Date Name Agenda Minutes'
38 | end
39 | end
40 | end
41 | end
42 |
43 | end
44 |
--------------------------------------------------------------------------------
/spec/helpers/application_helper_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe ApplicationHelper do
4 | describe "#should_have_ask_question_in_header?" do
5 | it "returns false when on a person's detail pages" do
6 | params[:controller] = "people"
7 | params[:action] = "show"
8 | expect(helper.should_have_ask_question_in_header?).to be_false
9 | end
10 |
11 | it "returns true when not on a person's detail pages" do
12 | params[:controller] = "pages"
13 | params[:action] = "index"
14 | expect(helper.should_have_ask_question_in_header?).to be_true
15 | end
16 | end
17 |
18 | describe "#is_image?" do
19 | it "returns false when file type is not present" do
20 | expect(helper.is_image?("")).to be_false
21 | end
22 |
23 | it "returns false when file type is not an image" do
24 | expect(helper.is_image?("http://example.com/file.html")).to be_false
25 | end
26 |
27 | it "returns true when file type is an image" do
28 | expect(helper.is_image?("http://example.com/file.png")).to be_true
29 | end
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/spec/lib/twitter_person_adapter_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 | require "twitter_person_adapter"
3 |
4 | describe TwitterPersonAdapter do
5 | let(:person) { Person.new }
6 | let(:twitter_user) { Twitter::User.new(id: 1234,
7 | screen_name: "HappyHappyJoyJoy") }
8 | let(:adapter) { TwitterPersonAdapter.new(person) }
9 |
10 | describe "#run" do
11 | it "takes twitter data and returns suitable attributes" do
12 | adapter.run twitter_user
13 | expect(person.read_attribute(:twitter_id)).to eq twitter_user.screen_name
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/spec/mailers/person_mailer_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe PersonMailer do
4 | before { ActionMailer::Base.deliveries.clear }
5 |
6 | it ".notify_staff_new_from_twitter sends staff member e-mail" do
7 | twitter = "xyz"
8 | person = FactoryGirl.create(:person)
9 | person.write_attribute(:twitter_id, twitter)
10 | person.save!
11 |
12 | staff_member = FactoryGirl.create(:user)
13 | staff_member.add_role :staff_member
14 |
15 | PersonMailer.notify_staff_new_from_twitter(person).deliver
16 | last_email = ActionMailer::Base.deliveries.last
17 |
18 | expect(last_email.to).to eq [staff_member.email]
19 | expect(last_email.subject).to eq "New person added from Twitter: #{twitter}"
20 | end
21 |
22 | it ".notify_staff_bad_person sends staff member e-mail" do
23 | cached_official = FactoryGirl.build(:cached_official)
24 | cached_official.person_id = nil
25 | cached_official.save!
26 |
27 | staff_member = FactoryGirl.create(:user)
28 | staff_member.add_role :staff_member
29 |
30 | PersonMailer.notify_staff_bad_person(cached_official).deliver
31 | last_email = ActionMailer::Base.deliveries.last
32 |
33 | expect(last_email.to).to eq [staff_member.email]
34 | expect(last_email.subject).to eq "Cached Official does not match person"
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/spec/models/agenda_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe Agenda do
4 | %w(url).each do |attribute|
5 | it {should validate_presence_of attribute}
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/spec/models/answer_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe Answer do
4 | %w(text question_id user_id).each do |attribute|
5 | it {should validate_presence_of attribute}
6 | end
7 |
8 | describe "#save" do
9 | context "when an answer is made featured" do
10 | it "should make all other answers unfeatured" do
11 | old_answer = FactoryGirl.create(:answer, featured: true)
12 | answer = FactoryGirl.create(:answer, featured: true)
13 | answer.update_attributes(featured: true)
14 | expect(old_answer.reload.featured?).to be_false
15 | end
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/spec/models/bill_detail_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe BillDetail do
4 | %w(state bill_id).each do |attribute|
5 | it {should validate_presence_of attribute}
6 | end
7 |
8 | context 'when in relation' do
9 | before :each do
10 | @metadatum = Metadatum.create(abbreviation: 'zz')
11 | @bill = Bill.create(state: 'zz')
12 | @record = BillDetail.create(bill: @bill)
13 | end
14 |
15 | it 'should retrieve a metadatum for a bill detail' do
16 | BillDetail.last.metadatum.should == @metadatum
17 | end
18 |
19 | it "should retrieve a bill's bill detail" do
20 | Bill.last.bill_detail.should == @record
21 | end
22 |
23 | it "should retrieve the bill detail's bill" do
24 | BillDetail.last.bill.should == @bill
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/spec/models/cached_officials_from_google_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe CachedOfficialsFromGoogle do
4 | let(:address) { "148 Lafayette St, New York, NY 10013"}
5 | let(:cached_officials) { CachedOfficialsFromGoogle.new(address) }
6 |
7 | describe "#each", :vcr do
8 | it "iterates over the collection of cached officials" do
9 | cached_official_names = cached_officials.map(&:name)
10 |
11 | expect(cached_official_names).to eq official_names
12 | end
13 |
14 | def official_names
15 | ["Daniel L Squadron", "Charles E. Schumer", "Kirsten E. Gillibrand",
16 | "Andrew M. Cuomo", "Bill de Blasio", "Jerrold Nadler", "Margaret Chin"]
17 | end
18 | end
19 |
20 | describe "if a matching cached_official exists" do
21 | it "returns existing official rather than creating a new one", :vcr do
22 | expect(CachedOfficialsFromGoogle.new(address).first.id)
23 | .to eq cached_officials.first.id
24 | end
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/spec/models/committee_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe Committee do
4 | let(:committee) { FactoryGirl.create(:committee) }
5 |
6 | describe "#name" do
7 | context "when subcommittee is present" do
8 | it "returns subcommittee value" do
9 | committee.write_attribute(:subcommittee, "sub")
10 | expect(committee.name).to eq "sub"
11 | end
12 | end
13 |
14 | context "when subcommittee is not present" do
15 | it "returns committee value" do
16 | committee.write_attribute(:committee, "committee")
17 | expect(committee.name).to eq "committee"
18 | end
19 | end
20 | end
21 |
22 | describe "#people" do
23 | context "when there are no people associated with a committee" do
24 | it "returns no results" do
25 | committee.write_attribute(:members, [])
26 | expect(committee.people.count).to eq 0
27 | end
28 | end
29 |
30 | context "when there are people on the committee" do
31 | it "returns people as result" do
32 | person = FactoryGirl.create(:person)
33 | committee.write_attribute(:members, [{ "leg_id" => person.id }])
34 | expect(committee.people.count).to eq 1
35 | end
36 | end
37 | end
38 | end
39 |
--------------------------------------------------------------------------------
/spec/models/councilmember_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe Councilmember do
4 | describe ".for_location" do
5 | before do
6 | @councilmember = Councilmember.create!(state: "pa-philadelphia")
7 | end
8 |
9 | it "returns matching people given a location", :vcr do
10 | address = "Philadelphia, PA"
11 | expect(Councilmember.for_location(address).first).to eq @councilmember
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/spec/models/county_official_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe CountyOfficial do
4 | describe ".for_location" do
5 | before do
6 | @county_official = CountyOfficial.create!(state: "ny-county-new-york")
7 | end
8 |
9 | it "returns matching people given a location", :vcr do
10 | address = "148 Lafayette St, New York, NY"
11 | expect(CountyOfficial.for_location(address).first).to eq @county_official
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/spec/models/federal_official_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe FederalOfficial do
4 | describe ".for_location" do
5 | before do
6 | @federal_official = FederalOfficial.create!(state: "us")
7 | end
8 |
9 | it "returns matching people given a location", :vcr do
10 | address = "148 Lafayette St, New York, NY"
11 | expect(FederalOfficial.for_location(address).first)
12 | .to eq @federal_official
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/models/geo_data_from_request_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | # set up and clear redis database
4 | describe GeoDataFromRequest do
5 | let(:ny_ip) { "72.43.115.186" }
6 | let(:fake_location) { "Fake New York, NY" }
7 |
8 | describe "#geo_data" do
9 | context "given a request object from within the US" do
10 | it "returns geo data result" do
11 | request = double
12 | request.stub(location: fake_location)
13 | request.stub(remote_addr: ny_ip)
14 |
15 | expect(GeoDataFromRequest.new(request).geo_data).to eq fake_location
16 | end
17 |
18 | context "when a request's IP has previously been used" do
19 | before do
20 | redis = Redis.new
21 | previous_geo_data = redis.get(ny_ip)
22 | set_ip_in(redis) unless previous_geo_data.present?
23 | end
24 |
25 | it "returns geo data result from cache rather than new lookup" do
26 | request = double
27 | request.stub(remote_addr: ny_ip)
28 | expect(GeoDataFromRequest.new(request).geo_data).to eq fake_location
29 | end
30 |
31 | def set_ip_in(redis)
32 | redis.set(ny_ip, Marshal.dump(fake_location))
33 | end
34 | end
35 | end
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/spec/models/governor_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe Governor do
4 | describe ".load_governors" do
5 | it "populates governor data for all states", :vcr do
6 | Governor.load_governors
7 | expect(Governor.count).to eq 50
8 | end
9 | end
10 |
11 | describe ".for_location" do
12 | before do
13 | @governor = Governor.create!(state: "vt")
14 | end
15 |
16 | it "returns matching people given a location", :vcr do
17 | address = "2227 Paine Turnpike South, Berlin, VT"
18 | expect(Governor.for_location(address).first).to eq @governor
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/spec/models/image_link_checker_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe ImageLinkChecker do
4 | describe "#accessible?", vcr: true do
5 | it "is true if url is available and its content type is an image" do
6 | url = "http://w3.legis.state.ak.us/images/senate/STG.jpg"
7 | expect(ImageLinkChecker.new(url).accessible?).to be_true
8 | end
9 |
10 | it "is false if url 404 or similar" do
11 | url = "http://www.askthem.io/some-bad-url"
12 | expect(ImageLinkChecker.new(url).accessible?).to be_false
13 | end
14 |
15 | it "is false if url's content type is not an image" do
16 | # returns a html page saying 404, but with 200 response
17 | url = "http://w3.legis.state.ak.us/images/senate/STGGGGG.jpg"
18 | expect(ImageLinkChecker.new(url).accessible?).to be_false
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/spec/models/image_src_url_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe ImageSrcUrl do
4 | describe "#is_image?" do
5 | it "is false if file or url is does't have image extension" do
6 | expect(ImageSrcUrl.new("/file.mov").is_image?).to be_false
7 | end
8 |
9 | it "is true if file or url does have image extension" do
10 | expect(ImageSrcUrl.new("/file.png").is_image?).to be_true
11 | end
12 |
13 | it "it recognizes image extension that have different capitalization" do
14 | expect(ImageSrcUrl.new("/file.JPG").is_image?).to be_true
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/spec/models/jurisdiction_id_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe JurisdictionId do
4 | describe "#id" do
5 | context "when only state given" do
6 | let(:options) { { state: "VT" } }
7 |
8 | it "returns state code result" do
9 | expect(JurisdictionId.new(options).id).to eq "vt"
10 | end
11 | end
12 |
13 | context "when state and municipality given" do
14 | let(:options) { { state: "VT", municipality: "Berlin" } }
15 |
16 | it "returns state code and municipal name result" do
17 | expect(JurisdictionId.new(options).id).to eq "vt-berlin"
18 | end
19 | end
20 |
21 | context "when state and county given" do
22 | let(:options) { { state: "VT", county: "Washington" } }
23 |
24 | it "returns state code and county name result with prefix" do
25 | expect(JurisdictionId.new(options).id).to eq "vt-county-washington"
26 | end
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/spec/models/location_formatter_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe LocationFormatter do
4 | describe "#format" do
5 | it "returns nil when location is invalid", :vcr do
6 | expect(LocationFormatter.new(0).format).to be_nil
7 | end
8 |
9 | it "returns geocode result for valid address", :vcr do
10 | formatted_location = LocationFormatter.new("05602").format
11 | expect(formatted_location.state_code).to eq "VT"
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/spec/models/mayor_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe Mayor do
4 | describe ".for_location" do
5 | before do
6 | @mayor = Mayor.create!(state: "ny-new-york")
7 | end
8 |
9 | it "returns matching people given a location", :vcr do
10 | address = "148 Lafayette St, New York, NY"
11 | expect(Mayor.for_location(address).first).to eq @mayor
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/spec/models/meeting_record_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe MinutesDocument do
4 | %w(url).each do |attribute|
5 | it {should validate_presence_of attribute}
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/spec/models/metadatum/state_spec.rb:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | require 'spec_helper'
3 |
4 | describe Metadatum::State do
5 | describe '.create_states_if_none' do
6 | context 'when the state jurisdictions already exist' do
7 | before :each do
8 | @metadata = []
9 | OpenGovernment::STATES.each do |key, value|
10 | @metadata << Metadatum.create(name: key, abbreviation: value)
11 |
12 | end
13 | end
14 |
15 | it 'does nothing because there is existing state Metadatum' do
16 | Metadatum::State.create_states_if_none
17 | metadata_count = Metadatum.count
18 | expect(metadata_count).to eq @metadata.size
19 | end
20 | end
21 |
22 | context 'when no state jurisdictions exist' do
23 | it 'creates a Metadatum with the states jurisdiction attributes', :vcr do
24 | Metadatum::State.create_states_if_none
25 | metadata_count = Metadatum.count
26 | expect(metadata_count).to eq OpenGovernment::STATES.size
27 | end
28 | end
29 | end
30 |
31 | describe '.create_states_from_api' do
32 | it 'creates states from api attributes', :vcr do
33 | Metadatum::State.create_states_from_api
34 | metadata_count = Metadatum.count
35 | expect(metadata_count).to eq OpenGovernment::STATES.size
36 | end
37 | end
38 | end
39 |
--------------------------------------------------------------------------------
/spec/models/metadatum/unaffiliated_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe Metadatum::Unaffiliated do
4 | describe ".find_or_create!" do
5 | context "when an unaffilated jurisdiction already exists" do
6 | before :each do
7 | @metadatum = Metadatum.create(abbreviation: "unaffiliated")
8 | end
9 |
10 | it "returns existing unaffiliated jurisdiction" do
11 | expect(Metadatum::Unaffiliated.find_or_create!).to eq @metadatum
12 | end
13 | end
14 |
15 | context "when no unaffilated jurisdiction exists" do
16 | it "creates a Metadatum with unaffilated jurisdiction attributes" do
17 | metadatum = Metadatum::Unaffiliated.find_or_create!
18 | expect(metadatum.attributes).to eq attributes
19 | end
20 |
21 | def attributes
22 | { abbreviation: "unaffiliated",
23 | "_id" => "unaffiliated",
24 | chambers: { "lower" => { "name" => "Unspecified", "title" => "" } },
25 | name: "Unaffiliated",
26 | legislature_name: "",
27 | default_city_for_state: false
28 | }.with_indifferent_access
29 | end
30 | end
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/spec/models/metadatum/us_spec.rb:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | require 'spec_helper'
3 |
4 | describe Metadatum::Us do
5 | describe '.find_or_create!' do
6 | context 'when a US jurisdiction already exists' do
7 | before :each do
8 | @metadatum = Metadatum.create(abbreviation: 'us')
9 | end
10 |
11 | it 'returns existing US jurisdiction' do
12 | expect(Metadatum::Us.find_or_create!).to eq @metadatum
13 | end
14 | end
15 |
16 | context 'when no US jurisdiction exists' do
17 | it 'creates a Metadatum with US jurisdiction attributes' do
18 | metadatum = Metadatum::Us.find_or_create!
19 | expect(metadatum.attributes).to eq attributes
20 | end
21 |
22 | def attributes
23 | { abbreviation: 'us',
24 | '_id' => 'us',
25 | chambers: { "upper" => { "name" => "Senate", "title" => "Senator" },
26 | "lower" => { "name" => "House", "title" => "Representative" } },
27 | name: "United States",
28 | legislature_name: "United States Congress",
29 | default_city_for_state: false
30 | }.with_indifferent_access
31 | end
32 | end
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/spec/models/metadatum_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe Metadatum do
4 | describe ".local_to" do
5 | it "returns metadatum that matches given locality and region" do
6 | metadatum = FactoryGirl.create(:metadatum, abbreviation: "ny-new-york")
7 | expect(Metadatum.local_to("New York", "NY")).to eq metadatum
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/spec/models/municipal_official_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe MunicipalOfficial do
4 | describe ".for_location" do
5 | before do
6 | @municipal_official = MunicipalOfficial.create!(state: "ny-new-york")
7 | end
8 |
9 | it "returns matching people given a location", :vcr do
10 | address = "148 Lafayette St, New York, NY"
11 | expect(MunicipalOfficial.for_location(address).first)
12 | .to eq @municipal_official
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/models/president_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe President do
4 | describe ".for_location" do
5 | before do
6 | @president = President.create!(state: "us")
7 | end
8 |
9 | it "returns matching people given a location", :vcr do
10 | address = "148 Lafayette St, New York, NY"
11 | expect(President.for_location(address).first).to eq @president
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/spec/models/state_legislator_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe StateLegislator do
4 | describe ".for_location" do
5 | before do
6 | # convoluted setting of id necessary, otherwise id gets generated
7 | @state_legislator = StateLegislator.new(state: "vt")
8 | @state_legislator.id = "VTL000008"
9 | @state_legislator.save!
10 | end
11 |
12 | it "returns matching people given a location", :vcr do
13 | address = "2227 Paine Turnpike South, Berlin, VT"
14 | expect(StateLegislator.for_location(address).first).to eq @state_legislator
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/spec/models/state_official_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe StateOfficial do
4 | describe ".for_location" do
5 | before do
6 | @state_official = StateOfficial.create!(state: "vt")
7 | end
8 |
9 | it "returns matching people given a location", :vcr do
10 | address = "2227 Paine Turnpike, Berlin, VT"
11 | expect(StateOfficial.for_location(address).first)
12 | .to eq @state_official
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/models/user_role_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe UserRole do
4 | context "when global role" do
5 | it "has unique name" do
6 | UserRole.create!(name: "staff_member")
7 | expect(UserRole.new(name: "staff_member").valid?).to be_false
8 | end
9 | end
10 |
11 | describe ".staff_members" do
12 | context "when no staff_member role exists" do
13 | it "returns an empty collection" do
14 | expect(UserRole.staff_members).to eq Array.new
15 | end
16 | end
17 |
18 | it "returns users that are staff members" do
19 | UserRole.create!(name: "staff_member")
20 | user = FactoryGirl.create(:user)
21 | user.add_role :staff_member
22 |
23 | expect(UserRole.staff_members).to eq [user]
24 | end
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/spec/models/vice_president_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe VicePresident do
4 | describe ".for_location" do
5 | before do
6 | @vice_president = VicePresident.create!(state: "us")
7 | end
8 |
9 | it "returns matching people given a location", :vcr do
10 | address = "148 Lafayette St, New York, NY"
11 | expect(VicePresident.for_location(address).first).to eq @vice_president
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/spec/support/disqus.rb:
--------------------------------------------------------------------------------
1 | # strangely facebook connect's js throws an error without this in test,
2 | # but not in production
3 | ENV["DISQUS_SHORTNAME"] ||= "dobot"
4 |
--------------------------------------------------------------------------------
/spec/support/files/teststrip.mpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opengovernment/askthem/4f5c2199c4818df929fa6b647b9271dcfbf66793/spec/support/files/teststrip.mpg
--------------------------------------------------------------------------------
/spec/uploaders/media_uploader_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe MediaUploader do
4 | describe "#extension_white_list" do
5 | it "resturns image and video extensions" do
6 | media = ImageSrcUrl::IMAGE_TYPES + VideoSrcUrl::VIDEO_TYPES
7 | expect(MediaUploader.new("/file.mov").extension_white_list).to eq media
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/spec/validators/user_email_matches_validator_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe UserEmailMatchesValidator do
4 | let(:identity) { FactoryGirl.build(:identity) }
5 |
6 | describe "#validate" do
7 | it "is valid when emails do match" do
8 | expect(identity.valid?).to be_true
9 | end
10 |
11 | it "is invalid when emails do not match" do
12 | user = identity.user
13 | user.email = "xxx"
14 | expect(identity.valid?).to be_false
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/spec/workers/geocode_worker_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe GeocodeWorker do
4 | describe '#perform' do
5 | it "should geocode the object's address", :vcr do
6 | user = FactoryGirl.create(:user)
7 | user.coordinates = nil
8 | user.save!
9 | GeocodeWorker.new.perform(user.id)
10 | expect(user.reload.to_coordinates).to eq [40.7195898, -73.9998334]
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/spec/workers/person_check_photo_url_worker_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe PersonCheckPhotoUrlWorker do
4 | describe '#perform' do
5 | context "when person's photo_url is not available" do
6 | it "the photo_url is archived", vcr: true do
7 | photo_url = "http://example.com/example.jpg"
8 | person = FactoryGirl.create(:person, photo_url: photo_url)
9 |
10 | PersonCheckPhotoUrlWorker.new.perform(person.id)
11 |
12 | person.reload
13 |
14 | expect(person.old_photo_urls).to eq [photo_url]
15 | expect(person.photo_url).to be_nil
16 | end
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/spec/workers/question_answered_notifier_worker_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe QuestionAnsweredNotifierWorker do
4 | describe '#perform' do
5 | before { ActionMailer::Base.deliveries.clear }
6 |
7 | it "sends emails to question author, staff, and signers" do
8 | answer = FactoryGirl.create(:answer)
9 | question = answer.question
10 | staff_member = FactoryGirl.create(:user)
11 | staff_member.add_role :staff_member
12 | signer = FactoryGirl.create(:user)
13 |
14 | QuestionAnsweredNotifierWorker.new.perform(question.id.to_s)
15 |
16 | delivery_count = ActionMailer::Base.deliveries.count
17 | # expect(delivery_count).to eq 3
18 | # only staff members for now
19 | expect(delivery_count).to eq 1
20 | end
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/spec/workers/question_coordinates_worker_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe QuestionCoordinatesWorker do
4 | describe '#perform' do
5 | it "sets coordinates based on user coordinates" do
6 | user = FactoryGirl.create(:user)
7 | question = FactoryGirl.create(:question, user: user)
8 | QuestionCoordinatesWorker.new.perform(question.id)
9 | expect(question.reload.coordinates).to eq [-73.9998334, 40.7195898]
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/spec/workers/unaffiliated_person_tidy_worker_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe UnaffiliatedPersonTidyWorker do
4 | describe '#perform' do
5 | it "destroys a person if they are unaffiliated and don't have a question" do
6 | person = FactoryGirl.create(:person,
7 | state: Metadatum::Unaffiliated::ABBREVIATION)
8 | UnaffiliatedPersonTidyWorker.new.perform(person.id)
9 | expect { person.reload }.to raise_error(Mongoid::Errors::DocumentNotFound)
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/spec/workers/user_set_local_jurisdiction_abbreviation_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe UserSetLocalJurisdictionAbbreviationWorker do
4 | describe '#perform' do
5 | it "sends email asking user to set their password" do
6 | user = FactoryGirl.create(:user)
7 |
8 | UserSetLocalJurisdictionAbbreviationWorker.new.perform(user.id)
9 |
10 | expect(user.reload.local_jurisdiction_abbreviation).to eq "ny-new-york"
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/spec/workers/user_set_password_notice_worker_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe UserSetPasswordNoticeWorker do
4 | describe '#perform' do
5 | before { ActionMailer::Base.deliveries.clear }
6 |
7 | context "when user is confirmed and has placeholder password" do
8 | it "sends email asking user to set their password" do
9 | user = FactoryGirl.create(:user)
10 | user.password_is_placeholder = true
11 | user.save!
12 |
13 | UserSetPasswordNoticeWorker.new.perform(user.id)
14 |
15 | last_email = ActionMailer::Base.deliveries.last
16 |
17 | expect(last_email.to).to eq [user.email]
18 | expect(last_email.subject).to eq "Set your AskThem.io password"
19 | end
20 | end
21 |
22 | context "when user is confirmed and has placeholder password, but email_is_disabled" do
23 | it "it does not send email asking user to set their password" do
24 | user = FactoryGirl.create(:user, email_is_disabled: true)
25 | user.password_is_placeholder = true
26 | user.save!
27 |
28 | expect { UserSetPasswordNoticeWorker.new.perform(user.id) }
29 | .to_not change { ActionMailer::Base.deliveries.count }.from(0).to(1)
30 | end
31 | end
32 | end
33 | end
34 |
--------------------------------------------------------------------------------