text:
Mass Tagging

Sometimes, tagging domains one-by-one just isn't enough. Welcome to metasmoke: now with mass tagging!

Using this filter...

    <%= form_tag domain_tags_mass_tagging_path, method: :get, class: 'form-inline' do %>
        <%= text_field_tag :filter, params[:filter], class: 'form-control input-sm', placeholder: 'Literal search, use * as wildcard' %>
        <%= submit_tag 'Filter', class: 'btn btn-primary btn-sm' %>
    <% end %>

...gets you these domains:

      Domain
      Occurrences

    <% @domains.each do |d| %>

          <%= d.domain %>
          <%= @counts[d.id] || 0 %>
          <%= link_to 'Details', spam_domain_path(d) %>
          <% if user_signed_in? && current_user.has_role?(:core) %>
              <%= link_to 'Edit', edit_spam_domain_path(d) %>
          <% end %>
          <% if user_signed_in? && current_user.has_role?(:admin) %>
              <%= link_to 'Delete', destroy_spam_domain_path(d), method: :delete, class: 'text-danger',
                              data: { confirm: 'Are you sure?' } %>
          <% end %>

    <% end %>

    <%= will_paginate @domains, renderer: BootstrapPagination::Rails %>

<% if @taggable %>

Tag all the above with this tag:

  <%= form_tag domain_tags_submit_tagging_path, method: :post, class: 'form-inline' do %>
    <%= hidden_field_tag :filter, params[:filter] %>
    <%= text_field_tag :tag, '', class: 'form-control input-sm', list: 'tag_list' %>
    <datalist id="tag_list">
      <% DomainTag.all.order(name: :asc).each do |t| %>
          <option value="<%= t.name %>"></option>
      <% end %>
    </datalist>
    <%= submit_tag 'Tag!', class: 'btn btn-primary btn-sm' %>
  <% end %>
<% else %>

(Add a filter to mass-tag domains)

<% end %>


text:
Domain Tagging

<%= form_tag domain_tags_path, method: :get, class: 'form-inline' do %>
  <%= text_field_tag :filter, params[:filter], class: 'form-control input-sm', placeholder: 'Search for tags' %>
  <%= check_box_tag :include_special, '1', params[:include_special] == '1' %>
  <%= label_tag :include_special, 'Include special tags?' %>
  <%= submit_tag 'Search', class: 'btn btn-primary btn-sm' %>
<% end %>

      Tag
      Domains

    <% @tags.each do |t| %>

        <span class="label label-<%= t.special? ? 'warning' : 'info' %>">#<%= t.name %> <%= t.description&.truncate(100) %>
        <%= @counts[t.id] || 0 %>
        <%= link_to 'Details', domain_tag_path(t) %>
        <% if user_signed_in? && current_user.has_role?(:core) %>
          <%= link_to 'Edit', edit_domain_tag_path(t) %>
        <% end %>
        <% if user_signed_in? && current_user.has_role?(:admin) %>
          <%= link_to 'Delete', destroy_domain_tag_path(t), method: :delete, class: 'text-danger',
                          data: { confirm: 'Are you sure?' } %>
        <% end %>

    <% end %>

<%= will_paginate @tags, renderer: BootstrapPagination::Rails %>

repo_name: Charcoal-SE/metasmoke

repo_language: Ruby

mime_type: text/plain


text:
<% if comment.user.id == -1 %>

      <%= safe_render_markdown(comment.text, scrubber: PostComment.scrubber) %>
      <%= time_ago_in_words comment.created_at %> ago

<% else %>
  <div class="panel panel-default abuse-comment" data-cid="<%= comment.id %>">

      <%= comment.user.username %>
      <span title="<%= comment.created_at %>"><%= time_ago_in_words comment.created_at %> ago
      <% if current_user == comment.user || current_user&.has_role?(:core) %>

        <%= link_to delete_abuse_comment_path(comment.id), method: :delete do %>

        <% end %>

      <% end %>

      <%= safe_render_markdown(comment.text, scrubber: PostComment.scrubber) %>

<% end %>


text:
Your Charcoal SpamWatch summary

Domains for <%= @group.name %>caught since <%= @last_email_date %>

Greetings,

<% if @domains.size == 0 %>

No domain names have been added to the domain group "<%= @group.name %>" since you were last emailed.

<% else %>

The following domain names have been added to the domain group "<%= @group.name %>" since you were last emailed.

    <% @domains.each do |sd| %>

<%= link_to sd.domain, sd.domain %>

    <% end %>

<% end %>

  Regards,

  Charcoal SpamWatch team

  Charcoal is not affiliated with and does not endorse the content of any websites linked or referred to in this email unless expressly stated otherwise.
  We recommend caution when accessing any of the linked websites in this email, as they may contain spam, malware, and/or work-inappropriate content.

  If you want to change your preferences or unsubscribe, you can do so
  <a href="https://metasmoke.erwaysoftware.com/email/preferences/show?token=<%= @addressee.manage_key %>">here.


text:
<%= form_for @domain, url: url do |f| %>

    <%= f.label :domain %>

    <%= f.text_field :domain, class: 'form-control', **(update ? {disabled: true} : {}) %>

    <%= f.label :whois, 'WHOIS' %>

    <%= f.text_area :whois, rows: 7, cols: 80, class: 'form-control' %>

    <%= f.submit 'Save', class: 'btn btn-primary' %>

<% end %>


text:
  Domain: <%= @domain.domain %>
  <% if @domain.domain_tags.special.any? %>

      <% @domain.domain_tags.special.each do |t| %>
        <%= render 'domain_tags/tag', tag: t %>
      <% end %>

  <% end %>

<% if user_signed_in? && (current_user.has_role?(:core) || current_user.has_role?(:admin)) %>

    <% if current_user.has_role?(:core) %>
      <%= link_to 'Edit', edit_spam_domain_path(@domain) %>
    <% end %>
    <% if current_user.has_role?(:core) %>
    · <%= link_to 'Fix ASN Tags', fix_asn_tags_path(@domain), method: :post,
    data: { confirm: 'Are you sure?' }, class: 'text-warning' %>
    <% end %>
    <% if current_user.has_role?(:admin) %>
      · <%= link_to 'Delete', destroy_spam_domain_path(@domain), method: :delete,
                    data: { confirm: 'Are you sure?' }, class: 'text-danger' %>
    <% end %>

<% end %>

    <% if @domain.domain_tags.standard.any? %>
      Tagged with:
      <% @domain.domain_tags.standard.each do |t| %>
        <%= render 'domain_tags/tag', tag: t, domain: @domain %>
      <% end %>
    <% else %>
      No tags.
    <% end %>

  <%= form_tag add_domain_tag_path, method: :post, class: 'form-inline add-domain-tag' do %>
    <%= hidden_field_tag :domain_id, @domain.id %>
    <%= select_tag :tag_name, options_for_select(DomainTag.all.map { |dt| [dt.name, dt.name, { 'data-subtext' => dt.description&.truncate(100) }] }),
                   class: 'selectpicker', include_blank: true %>
    <%= submit_tag 'Add', class: 'btn btn-primary' %>
  <% end %>

<% if current_user&.has_role?(:core) %>
  <%= render 'abuse_reports/list', item: @domain %>
<% end %>

<% if @domain.whois.present? %>

<%= @domain.whois %>

<% else %>

No whois data available.

<% end %>

Linked domains

Link a domain

  <% @domain.links.each do |l| %>
    <%= render 'domain_links/link', link: l, domain: @domain %>
  <% end %>

Posts

This domain has been seen in <%= pluralize @counts[:all], 'post' %>, <%= @counts[:tp] %> TP.

    <% @posts.includes_for_post_row.each do |post| %>
      <%= render 'posts/post', post: post %>
    <% end %>

<%= will_paginate @posts, renderer: BootstrapPagination::Rails %>

        <button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>

New Domain Link

        <%= form_for DomainLink.new, url: create_domain_link_path, remote: true, class: 'domain-link-form' do |f| %>
          <%= f.hidden_field :left_id, value: @domain.id %>

            <%= f.label :right_id, 'Linked domain' %>

            <%= f.select :right_id, [], { include_blank: true }, class: 'form-control selectpicker',
                         data: { remote_source: spam_domains_query_path, none_selected_text: 'Start typing to search for domains...'},
                         required: true %>

            <%= f.label :link_type, 'Why are these linked?' %>

            <%= f.select :link_type, options_for_select(DomainLink.link_types.map { |lt| [lt, lt] }), { include_blank: true },
                         class: 'form-control selectpicker', data: { none_selected_text: 'Pick an existing reason or type your own' },
                         required: true %>

            <%= f.label :comments, 'Additional comments' %>

            <%= f.text_area :comments, rows: 5, cols: 100, placeholder: 'Expand on details here if necessary', class: 'form-control' %>

              <%= f.submit 'Link', class: 'btn btn-success' %>

        <% end %>


text:
Create Spam Domain

<%= render 'form', url: create_no_post_spam_domain_path, update: false %>


text:
<% post_id ||= nil %>
<%
counts_summary = PostSpamDomain.joins(:post)
                               .where(posts_spam_domains: {spam_domain_id: domain.id})
                               .select('COUNT(*) as total, SUM(is_tp) as tp, SUM(is_fp) as fp, SUM(is_naa) as naa')
                               .first
occurances ||= false
%>

  <% if occurances && counts_summary[:total] > 0 %>
    <% if counts_summary[:tp] == 0 %>
      ✗
    <% end %>
    <% if counts_summary[:fp] == 0 %>
      ✓
    <% end %>
  <% end %>
  <%= link_to domain.domain, spam_domain_path(domain) %>
  <% if occurances %>
    (<%= counts_summary[:tp] %>,
    <%= counts_summary[:fp] %>,
    <%= counts_summary[:naa] %>)
  <% end %>
  <% domain.domain_tags.each do |t| %>
    <%= render 'domain_tags/tag', tag: t, domain: domain %>
  <% end %>


text:
Editing: <%= @domain.domain %>

<%= render 'form', url: update_spam_domain_path, update: true %>


text:
<%= render 'review_queues/responses', queue: queue, item: item %>
<% domain = item.reviewable %>

Domain: <%= domain.domain %>

<% if user_signed_in? && (current_user.has_role?(:core) || current_user.has_role?(:admin)) %>

    <% if current_user.has_role?(:core) %>
      <%= link_to 'Edit', edit_spam_domain_path(domain) %>
    <% end %>
    <% if current_user.has_role?(:admin) %>
      · <%= link_to 'Delete', destroy_spam_domain_path(domain), method: :delete,
                              data: { confirm: 'Are you sure?' }, class: 'text-danger' %>
    <% end %>

<% end %>

    <% if domain.domain_tags.any? %>
      Tagged with:
      <% domain.domain_tags.each do |t| %>
        <%= render 'domain_tags/tag', tag: t, domain: domain %>
      <% end %>
    <% else %>
      No tags.
    <% end %>

  <%= form_tag review_add_tag_path, method: :post, class: 'form-inline pull-left review-add-domain-tag', remote: true,
               data: { deduplicate: true } do %>
    <%= hidden_field_tag :domain_id, domain.id %>
    <%= select_tag :tag_name, options_for_select(DomainTag.all.map { |dt| [dt.name, dt.name, { 'data-subtext' => dt.description&.truncate(100) }] }),
                   class: 'selectpicker', include_blank: true %>
    <%= submit_tag 'Add', class: 'btn btn-primary' %>
  <% end %>

<% if domain.whois.present? %>

<%= domain.whois %>

<% else %>

No whois data available.

<% end %>

    <% @sites = Site.where(id: domain.posts.order(id: :desc).limit(100).map { |p| p.site_id }) %>
    <% domain.posts.limit(100).order(id: :desc).includes_for_post_row.each do |post| %>
      <%= render 'posts/post', post: post %>
    <% end %>


text:
Domain Tracking

Tracking <%= pluralize(@total, 'domain') %> in total. To apply one tag to many domains, use the
  <%= link_to 'mass tagging tool', :domain_tags_mass_tagging %>. You can also <%= link_to 'add a new domain', new_spam_domain_path %>.

<%= form_tag spam_domains_path, method: :get, class: 'form-inline' do %>
  <%= text_field_tag :filter, params[:filter], class: 'form-control input-sm' %>
  <%= submit_tag 'Search', class: 'btn btn-primary btn-sm' %>
<% end %>

      Domain
      Occurrences
      Tags

    <% @domains.each do |d| %>

        <%= d.domain %>

          <%= d.post_counts[:all] || 0 %>
          (<%= d.post_counts[:tp] || 0 %>,
          <%= d.post_counts[:fp] || 0 %>,
          <%= d.post_counts[:naa] || 0 %>)

          <% d.domain_tags.each do |tag| %>
            <%= render 'domain_tags/tag', tag: tag, domain: d %>
          <% end %>

        <%= link_to 'Details', spam_domain_path(d) %>
        <% if user_signed_in? && current_user.has_role?(:core) %>
          <%= link_to 'Edit', edit_spam_domain_path(d) %>
        <% end %>
        <% if user_signed_in? && current_user.has_role?(:admin) %>
          <%= link_to 'Delete', destroy_spam_domain_path(d), method: :delete, class: 'text-danger',
                          data: { confirm: 'Are you sure?' } %>
        <% end %>

    <% end %>

<%= will_paginate @domains, renderer: BootstrapPagination::Rails %>


text:
New API key

From this page, you can register a new API key. The key is pre-set for you for security; copy it and add a name for
  the app (or user) that will use it, then click Register.

<%= form_for @key, url: url_for(controller: :api_keys, action: :create) do |f| %>

    <%= f.label :key %>

    <%= f.text_field :key, value: @key.key, class: "form-control" %>

    <%= f.label :app_name %>

    <%= f.text_field :app_name, class: "form-control" %>

    <%= f.label :user_id, "Owner" %>

    <%= f.select :user_id, options_for_select(User.all.map{|u| [u.username, u.id]}), { include_blank: true }, { class: "form-control" } %>

    <%= f.label :key_type %>

    <%= f.select :key_type, options_for_select([['Standard', 'standard'], ['Read-only', 'read_only']]),
                 { class: 'form-control' } %>

    <%= f.label :github_link, "GitHub repository link" %>

    <%= f.text_field :github_link, class: "form-control" %>

    <%= f.submit "Register", class: "btn btn-primary" %>

<% end %>


text:
Your API Keys

This is a list of all the API keys which you are registered as the owner of. If you wish, you can edit your keys
  to change or include the app's name or a link to GitHub. You can also revoke all write tokens for your app in case
  of a security breach - this deactivates all active write tokens, so users of your app will need to re-authenticate
  to use it again. Use this sparingly and only when necessary.

      Key String
      App Name
      GitHub
      Owner
      Created

    <% @keys.each do |key| %>

        <%= key.key %>
        <%= key.app_name %>
        <%= link_to "Repo", key.github_link %>
        <%= key.user.username %>
        <%= time_ago_in_words(key.created_at) %> ago
        <%= link_to "Edit", url_for(controller: :api_keys, action: :owner_edit, id: key.id) %>
        <%= link_to "Revoke write tokens", url_for(controller: :api_keys, action: :owner_revoke, id: key.id), method: :delete, class: "text text-danger", data: { confirm: 'Are you sure?' } %>

    <% end %>


text:
Edit API key

<%= form_for @key, url: url_for(controller: :api_keys, action: :owner_update) do |f| %>

    <%= f.label :app_name %>

    <%= f.text_field :app_name, class: "form-control" %>

    <%= f.label :github_link, "GitHub repository link" %>

    <%= f.text_field :github_link, class: "form-control" %>

    <%= f.submit "Save", class: "btn btn-primary" %>

<% end %>


text:
Edit API key

<%= form_for @key, url: url_for(controller: :api_keys, action: :update) do |f| %>

    <%= f.label :key %>

    <%= f.text_field :key, value: @key.key, class: "form-control" %>

    <%= f.label :app_name %>

    <%= f.text_field :app_name, class: "form-control" %>

    <%= f.label :user_id, "Owner" %>

    <% if @key.user %>
      <%= f.select :user_id, options_for_select(User.all.map{|u| [u.username, u.id]}, [@key.user.username, @key.user.id]),
          { include_blank: true }, { class: "form-control" } %>
    <% else %>
      <%= f.select :user_id, options_for_select(User.all.map{|u| [u.username, u.id]}), { include_blank: true }, { class: "form-control" } %>
    <% end %>

    <%= f.label :github_link, "GitHub repository link" %>

    <%= f.text_field :github_link, class: "form-control" %>

    <%= f.submit "Save", class: "btn btn-primary" %>

<% end %>


text:
Registered API Keys

      Key String
      App Name
      GitHub
      Owner
      Created
      Trusted

    <% @keys.each do |key| %>

        <%= key.key %>
        <%= key.app_name %>
        <%= link_to "Repo", key.github_link %>

          <% if key.user %>
            <%= key.user.username %>
          <% else %>
            (No owner)
          <% end %>

        <%= time_ago_in_words(key.created_at) %> ago
        <input type="checkbox" class="trust-checkbox" data-key-id="<%= key.id %>" <%= "checked" if key.is_trusted %> />
        <%= link_to "Edit", url_for(controller: :api_keys, action: :edit, id: key.id) %>
        <%= link_to "Revoke write tokens", url_for(controller: :api_keys, action: :revoke_write_tokens, id: key.id), method: :delete, class: "text text-danger", data: { confirm: 'Are you sure?' } %>

    <% end %>

<%= link_to "New API key", admin_new_key_url %>


text:
<% feedback ||= comment.post.feedbacks.to_a.select { |f| f.user_id == comment.user_id }[0] %>
<div class="panel panel-primary post-comment" data-cid="<%= comment.id %>">

    <%= comment.user&.username || '(deleted user)' %>
    <% if feedback.present? && !@is_review_item %>
      <%= render 'feedbacks/feedback', feedback: feedback %>
    <% end %>
    <span title="<%= comment.created_at %>"><%= time_ago_in_words comment.created_at %> ago
    <% if current_user == comment.user || current_user&.has_role?(:admin) %>

        <%= link_to delete_comment_path(comment.id), method: :delete do %>

        <% end %>

    <% end %>

    <%= safe_render_markdown(comment.text, scrubber: PostComment.scrubber) %>


text: <%= yield %>


text:
<!DOCTYPE html>

  <title>
    <%= if content_for?(:title) then yield(:title) + ' - ' end %>
    metasmoke
  </title>

  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

  <% Rack::MiniProfiler.step('Rendering: layouts/application/head') do %>
    <% cache "application/head_tags" do %>
      <%= stylesheet_link_tag 'application', media: 'all' %>
      <%= favicon_link_tag '/favicon.ico' %>
      <link rel="search" type="application/opensearchdescription+xml" title="metasmoke"
            href="https://metasmoke.erwaysoftware.com/opensearch.xml">

      <%= stylesheet_link_tag "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" %>
      <%= stylesheet_link_tag "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.1/css/bootstrap-select.min.css" %>
      <%= stylesheet_link_tag "https://charcoal-se.org/assets/css/branding.css" %>
      <%= stylesheet_link_tag "https://use.fontawesome.com/releases/v5.2.0/css/all.css", integrity: "sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ", crossorigin: "anonymous" %>

      <%= javascript_include_tag "https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js" %>
      <%= javascript_include_tag "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" %>
      <%= javascript_include_tag "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js" %>
      <%= javascript_include_tag "https://cdnjs.cloudflare.com/ajax/libs/highcharts/10.3.3/highcharts.js", "chartkick" %>
    <% end %>
    <%= javascript_pack_tag 'vendor', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%= csrf_meta_tags %>
    <%= action_cable_meta_tag %>
  <% end %>

<body class="<%= controller.class.name.sub(/Controller$/, '').underscore.dasherize %>">
  <nav class="navbar navbar-default navbar-static-top <%= "navbar-inverse" unless Rails.env.production? %>">

        <button type="button" class="navbar-toggle status-<%= SmokeDetector.status_color %> collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
          Toggle navigation

        </button>
        by Charcoal
        metasmoke

      <% Rack::MiniProfiler.step('Rendering: layouts/application/nav') do %>

          <%= nav_link PostsController, class: 'nav-tab-posts' %>
          <% if !user_signed_in? %>
            <%= nav_link GraphsController, label: 'graphs', class: 'nav-tab-graphs' %>
          <% end %>

          <% flagging_status = FlagSetting['flagging_enabled'] == '0' ? 'critical' : (FlagSetting['dry_run'] == '1' ? 'warning' : 'good') %>
          <li class="nav-tab-search <%= (controller.class == SearchController && controller.action_name.to_sym == :index) ? "active" : "" %>">
            <%= link_to 'search', search_path, class: 'nav-search-link' %>
            <%= link_to '', search_path, class: 'nav-search-link glyphicon glyphicon-search', title: 'search' %>

          <li class="nav-tab-flagging status status-<%= flagging_status %> <%= (controller.class == FlagSettingsController && controller.action_name.to_sym == :dashboard) ? "active" : "" %>">
            <%= link_to 'flagging', flagging_path, class: 'nav-flagging-link' %>
            <%= link_to '', flagging_path, class: 'nav-flagging-link glyphicon glyphicon-flag', title: 'flagging' %>

          <li class='nav-tab-reasons <%= (controller.class == DashboardController && controller.action_name == :index) ? "active" : "" %>'><%= link_to "reasons", reasons_path %>

          <% Rack::MiniProfiler.step('Rendering: layouts/application/nav/review') do %>
          <% if user_signed_in? && current_user.has_role?("reviewer") %>
            <% q_counts = redis.smembers("review_queues").map { |i| [i.to_i, redis.scard("review_queue/#{i}/unreviewed")] }.to_h %>
            <% total_count = q_counts.sum { |_k, v| v } %>
            <% label = raw("review #{total_count != 0 && current_user&.has_role?(:reviewer) ? total_count : nil}") %>
            <% Rack::MiniProfiler.step('Rendering: layouts/application/nav/review/dropdown') do %>
            <%= nav_dropdown ReviewQueuesController, label: label do %>
              <% ReviewQueue.where(privileges: current_user.roles.map(&:name)).each do |rq| %>

                  <%= link_to review_queue_path(rq.name) do %>
                    <%= rq.name.titleize %> <%= q_counts[rq.id] unless q_counts[rq.id] == 0 %>
                  <% end %>

              <% end %>
            <% end %>
            <% end %>
          <% end %>
          <% end %>
          <%= nav_dropdown AdminController, label: 'tools' do %>
            <%= nav_link SpamDomainsController, label: 'Domains' %>
            <%= nav_link DomainTagsController, label: 'Domain Tags' %>
            <%= nav_link DomainGroupsController, label: 'Domain Groups' %>

            <%= nav_link DashboardController, action: :site_dash, label: 'Site Dashboard' %>
            <%= nav_link GraphsController, label: 'Graphs' %>
            <%= nav_link StackExchangeUsersController, label: 'Spammers', action: :sites %>
          <% end %>

          <% if current_user&.has_role?(:core) %>
            <%= nav_dropdown DashboardController, action: 'new_dash', label: 'core' do %>
              <% unless current_user&.has_role?(:admin) %>
                <%= nav_link AdminController, label: 'User Data & Roles', action: :users %>

              <% end %>
              <%= nav_link AdminController, label: 'Invalidated Feedback', action: :recently_invalidated %>
              <%= nav_link AdminController, label: 'Feedback via API', action: :api_feedback %>

              <% if Announcement.current.count > 0 %>
                <%= nav_link AnnouncementsController, label: 'Announcements' do %>
                  <%= Announcement.current.count %>
                <% end %>
              <% else %>
                <%= nav_link AnnouncementsController, label: 'Announcements' %>
              <% end %>

              <%= nav_link nil, path: '/data/sql', label: 'SQL Data Exploder' %>
              <%= nav_link false, path: '/api/graphql', label: 'GraphQL Data Exploder' %>
              <%= nav_link false, path: '/api/graphiql', label: 'GraphiQL Data Exploder' %>

              <%= nav_link AbuseReportsController, label: 'Abuse Reports', action: :index %>
              <% unless current_user&.has_role?(:developer) %>

                <%= nav_link DumpsController, label: 'Database Dumps', action: :index %>
              <% end %>
            <% end %>
          <% end %>

          <% if current_user&.has_role?(:admin) %>
            <%= nav_dropdown AdminController, label: 'admin' do %>
              <%= nav_link AdminController, label: 'User Data & Roles', action: :users %>
              <%= nav_link APIKeysController, label: 'API Keys' %>
              <%= nav_link SiteSettingsController, label: 'Website Configuration' %>
              <%= nav_link SpamWavesController, label: 'Spam Waves' %>
            <% end %>
          <% end %>

          <% if current_user&.has_role?(:developer) %>
            <%= nav_dropdown DashboardController, action: 'new_dash', label: 'dev' do %>
              <%= nav_link DumpsController, label: 'Database Dumps', action: :index %>
              <%= nav_link DeveloperController, label: 'Production log', action: :production_log %>
              <%= nav_link RedisLogController, label: 'Request log', action: :index %>
            <% end %>
          <% end %>

          <%= nav_link StatusController, attrs: {
            id: 'smokedetector-status',
            class: ["nav-tab-SD-status", 'status', "status-#{SmokeDetector.status_color}"],
            data: {
              last_ping: SmokeDetector.select(:last_ping).order(last_ping: :desc).first&.last_ping&.to_f,
              toggle: 'tooltip',
              placement: 'bottom'
            }
          } %>

          <% if user_signed_in? %>
            <%= nav_dropdown label: current_user.username || current_user.email do %>
              <%= nav_link CustomSessionsController, label: 'Sign Out', action: :destroy, link_attrs: { method: 'delete' } %>
              <%= nav_link CustomRegistrationsController, label: 'Account Settings', action: :edit %>
              <%= nav_link UsersController, action: :apps, label: 'Apps' %>
              <% if current_user.has_role? :smoke_detector_runner %>
                <%= nav_link SmokeDetectorsController, label: 'My SmokeDetectors', action: :mine %>
              <% end %>
              <%= nav_link AdminController, label: 'My Feedback', params: { user_id: current_user.id }, action: :user_feedback %>
              <% if session[:impersonator_id].present? %>
                <%= nav_link DeveloperController, action: :change_back, label: 'Stop impersonating' %>
              <% end %>
            <% end %>
          <% else %>
            <%= nav_link CustomSessionsController, label: 'sign in', action: :new, class: 'nav-tab-sign-in' %>
            <%= nav_link CustomRegistrationsController, label: 'sign up', action: :new , class: 'nav-tab-sign-up' %>
          <% end %>
          <% if CurrentCommit.present? %>
            <%= nav_link CodeStatusController, label: '', attrs: {
              title: "Controller: #{controller.class}##{controller.action_name}",
              class: 'nav-tab-current-commit commit-sha',
              data: {
                sha: CurrentCommit
              }
            } do %>
              <%= CurrentCommit.first(7) %>
            <% end %>
          <% end %>

    <% end %>

    <% Rack::MiniProfiler.step('Rendering: layouts/application/announcements') do %>

      This page has been updated. Refresh to get the latest version.

    <% flash.each do |key, value| %>
      <% if %w[primary secondary success danger warning info light dark message alert muted].include? key.to_s %>
        <div class="alert alert-<%= key %>"><%= value %>

      <% end %>
    <% end %>

    <% if Announcement.current.count > 0 %>

Hide announcements

        <% Announcement.current.each do |a| %>
          <%= render "announcements/announcement", announcement: a %>
        <% end %>

    <% end %>
    <% end %>
    <%= yield %>

        We are Charcoal (not Stack Exchange). We make nice things.

        chat • security • contact

        Post content sourced from the Stack Exchange Network.


text:
<html>
  <body>
    <%= yield %>
  </body>
</html>


text:
#!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
load Gem.bin_path('bundler', 'bundle')


text:
#!/usr/bin/env ruby
require_relative '../config/boot'
require 'rake'
Rake.application.run


text:
#!/usr/bin/env ruby

# This file loads spring without using Bundler, in order to be fast.
# It gets overwritten when you run the `spring binstub` command.

unless defined?(Spring)
  require "rubygems"
  require "bundler"

  if match = Bundler.default_lockfile.read.match(/^GEM$.*?^    (?:  )*spring \((.*?)\)$.*?^$/m)
    Gem.paths = { "GEM_PATH" => [Bundler.bundle_path.to_s, *Gem.path].uniq }
    gem "spring", match[1]
    require "spring/binstub"
  end
end


text:
#!/usr/bin/env ruby
require 'pathname'
require 'fileutils'
include FileUtils

# path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)

def system!(*args)
  system(*args) || abort("\n== Command #{args} failed ==")
end

chdir APP_ROOT do
  # This script is a starting point to setup your application.
  # Add necessary setup steps to this file.

  puts '== Installing dependencies =='
  system! 'gem install bundler --conservative'
  system('bundle check') or system!('bundle install')

  # puts "\n== Copying sample files =="
  # unless File.exist?('config/database.yml')
  #   cp 'config/database.yml.sample', 'config/database.yml'
  # end

  puts "\n== Preparing database =="
  system! 'bin/rails db:setup'

  puts "\n== Removing old logs and tempfiles =="
  system! 'bin/rails log:clear tmp:clear'

  puts "\n== Restarting application server =="
  system! 'bin/rails restart'
end


text:
#!/usr/bin/env ruby
$stdout.sync = true

require "shellwords"
require "yaml"

ENV["RAILS_ENV"] ||= "development"
RAILS_ENV = ENV["RAILS_ENV"]

ENV["NODE_ENV"] ||= RAILS_ENV
NODE_ENV = ENV["NODE_ENV"]

APP_PATH          = File.expand_path("../", __dir__)
NODE_MODULES_PATH = File.join(APP_PATH, "node_modules")
WEBPACK_CONFIG    = File.join(APP_PATH, "config/webpack/#{NODE_ENV}.js")

unless File.exist?(WEBPACK_CONFIG)
  puts "Webpack configuration not found."
  puts "Please run bundle exec rails webpacker:install to install webpacker"
  exit!
end

newenv  = { "NODE_PATH" => NODE_MODULES_PATH.shellescape }
cmdline = ["yarn", "run", "webpack", "--", "--config", WEBPACK_CONFIG] + ARGV

Dir.chdir(APP_PATH) do
  exec newenv, *cmdline
end


text:
#!/usr/bin/env ruby
require 'pathname'
require 'fileutils'
include FileUtils

# path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)

def system!(*args)
  system(*args) || abort("\n== Command #{args} failed ==")
end

chdir APP_ROOT do
  # This script is a way to update your development environment automatically.
  # Add necessary update steps to this file.

  puts '== Installing dependencies =='
  system! 'gem install bundler --conservative'
  system 'bundle check' or system! 'bundle install'

  puts "\n== Updating database =="
  system! 'bin/rails db:migrate'

  puts "\n== Removing old logs and tempfiles =="
  system! 'bin/rails log:clear tmp:clear'

  puts "\n== Restarting application server =="
  system! 'bin/rails restart'
end


text:
#!/usr/bin/env ruby

if ENV['RAILS_ENV'] == 'test'
  require 'simplecov'
  SimpleCov.start 'rails'
  puts "required simplecov"
end

APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rails/commands'


text:
#!/usr/bin/env ruby
$stdout.sync = true

require "shellwords"
require "yaml"

ENV["RAILS_ENV"] ||= "development"
RAILS_ENV = ENV["RAILS_ENV"]

ENV["NODE_ENV"] ||= RAILS_ENV
NODE_ENV = ENV["NODE_ENV"]

APP_PATH          = File.expand_path("../", __dir__)
CONFIG_FILE       = File.join(APP_PATH, "config/webpacker.yml")
NODE_MODULES_PATH = File.join(APP_PATH, "node_modules")
WEBPACK_CONFIG    = File.join(APP_PATH, "config/webpack/development.js")

def args(key)
  index = ARGV.index(key)
  index ? ARGV[index + 1] : nil
end

begin
  dev_server = YAML.load_file(CONFIG_FILE)["development"]["dev_server"]

  DEV_SERVER_HOST = "http#{"s" if args('--https') || dev_server["https"]}://#{args('--host') || dev_server["host"]}:#{args('--port') || dev_server["port"]}"

rescue Errno::ENOENT, NoMethodError
  puts "Webpack dev_server configuration not found in #{CONFIG_FILE}."
  puts "Please run bundle exec rails webpacker:install to install webpacker"
  exit!
end

newenv = {
  "NODE_PATH" => NODE_MODULES_PATH.shellescape,
  "ASSET_HOST" => DEV_SERVER_HOST.shellescape
}.freeze

cmdline = ["yarn", "run", "webpack-dev-server", "--progress", "--color", "--config", WEBPACK_CONFIG] + ARGV

Dir.chdir(APP_PATH) do
  exec newenv, *cmdline
end


text:
namespace :custom do
    task :symlink_db_yml do
      run "ln -s #{shared_path}/config/database.yml #{release_path}/config/database.yml"
    end
end


text:
SELECT
  post_id,
  tp_count,
  fp_count,
  naa_count
FROM (
  SELECT
   posts.id AS post_id,
   posts.is_tp AS is_tp,
   posts.is_fp AS is_fp,
   posts.is_naa AS is_naa,
   COUNT(DISTINCT IF(feedbacks.feedback_type LIKE 't%', feedbacks.id, NULL)) AS tp_count,
   COUNT(DISTINCT IF(feedbacks.feedback_type LIKE 'f%', feedbacks.id, NULL)) AS fp_count,
   COUNT(DISTINCT IF(feedbacks.feedback_type LIKE 'n%', feedbacks.id, NULL)) AS naa_count
  FROM p_posts AS posts
   INNER JOIN p_feedbacks AS feedbacks ON posts.id = feedbacks.post_id
  WHERE
   posts.is_tp = TRUE AND
   (posts.is_fp = TRUE OR posts.is_naa = TRUE) AND
   feedbacks.is_invalidated = FALSE
  GROUP BY posts.id
) AS feedback_info
WHERE
  (tp_count = 0 AND is_tp = TRUE) OR
  (fp_count = 0 AND is_fp = TRUE) OR
  (naa_count = 0 AND is_naa = TRUE)
ORDER BY post_id DESC;


text:
SELECT TRUNCATE(weight, -1), COUNT(id) FROM
(SELECT posts.id, posts.is_tp, SUM(reasons.weight) AS weight FROM posts INNER JOIN posts_reasons ON posts.id = posts_reasons.post_id
INNER JOIN reasons ON posts_reasons.reason_id = reasons.id GROUP BY posts.id) AS posts_weights
WHERE is_tp = 0
GROUP BY TRUNCATE(weight, -1)
ORDER BY TRUNCATE(weight, -1) ASC;


text:
SELECT TRUNCATE(weight, -1), COUNT(id) FROM
(SELECT posts.id, posts.is_tp, SUM(reasons.weight) AS weight FROM posts INNER JOIN posts_reasons ON posts.id = posts_reasons.post_id
INNER JOIN reasons ON posts_reasons.reason_id = reasons.id GROUP BY posts.id) AS posts_weights
GROUP BY TRUNCATE(weight, -1)
ORDER BY TRUNCATE(weight, -1) ASC;


text:
SELECT
  (1 - (COUNT(DISTINCT IF(t.is_fp OR t.is_naa, t.id, NULL)) / COUNT(DISTINCT t.id))) * 100 AS accuracy
FROM (
  SELECT
    DISTINCT x.id,
    x.is_tp,
    x.is_fp,
    x.is_naa,
    x.fc_id
  FROM (
    SELECT
      fc.id AS 'fc_id',
      p.id,
      p.is_tp,
      p.is_fp,
      p.is_naa
    FROM flag_conditions AS fc
      INNER JOIN flag_conditions_sites AS fcs ON fcs.flag_condition_id = fc.id
      INNER JOIN (
        SELECT
          posts.id,
          posts.is_tp,
          posts.is_fp,
          posts.is_naa,
          posts.user_reputation,
          posts.site_id,
          SUM(reasons.weight) AS reason_weight,
          COUNT(DISTINCT reasons.id) AS reason_count
        FROM posts
          INNER JOIN posts_reasons ON posts.id = posts_reasons.post_id
          INNER JOIN reasons ON reasons.id = posts_reasons.reason_id
        GROUP BY posts.id
    ) AS p ON
      p.reason_count >= fc.min_reason_count AND
      p.user_reputation <= fc.max_poster_rep AND
      p.reason_weight >= fc.min_weight AND
      p.site_id = fcs.site_id
    WHERE
      fc.user_id = :user_id AND
      fc.flags_enabled = TRUE
  ) AS x
) AS t;


text:
SELECT TRUNCATE(weight, -1), COUNT(id) FROM
(SELECT posts.id, posts.is_tp, SUM(reasons.weight) AS weight FROM posts INNER JOIN posts_reasons ON posts.id = posts_reasons.post_id
INNER JOIN reasons ON posts_reasons.reason_id = reasons.id GROUP BY posts.id) AS posts_weights
WHERE is_tp = 1
GROUP BY TRUNCATE(weight, -1)
ORDER BY TRUNCATE(weight, -1) ASC;


text:
namespace :grape do
  desc 'Print grape API routes'
  task routes: :environment do
    API::Base.routes.each do |route|
      puts "#{route.options[:method]} #{route.path}"
    end
  end
end


text:
# frozen_string_literal: true

require 'simplecov'
require 'webmock/minitest'
SimpleCov.start 'rails'

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'

module ActiveSupport
  class TestCase
    include ActiveJob::TestHelper
    # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
    fixtures :all

    # Add more helper methods to be used by all tests here...
  end
end

module ActionController
  class TestCase
    include Devise::Test::ControllerHelpers
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class ReviewItemTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class AbuseReportStatusTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class AnnouncementTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class AbuseReportTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class SpamDomainTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class AbuseContactTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class SmokeDetectorTest < ActiveSupport::TestCase
  test 'should check Smokey status' do
    s = SmokeDetector.order(Arel.sql('last_ping DESC')).first
    SmokeDetector.check_smokey_status

    assert_not_equal s.email_date, SmokeDetector.order(Arel.sql('last_ping DESC')).first.email_date
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class FlagTest < ActiveSupport::TestCase
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class UserTest < ActiveSupport::TestCase
  test 'user record should be deletable' do
    post = Post.last

    u = User.new
    u.username = 'Awesome Name'
    u.save!(validate: false)

    u.flag_conditions.new.save!(validate: false)
    u.flag_logs.new.save!(validate: false)
    u.api_tokens.new.save!(validate: false)
    u.api_keys.new.save!(validate: false)
    u.user_site_settings.new.save!(validate: false)
    u.feedbacks.new(feedback_type: 'tpu-', post: post).save!(validate: false)
    u.smoke_detectors.new.save!(validate: false)
    u.moderator_sites.new.save!(validate: false)

    assert_difference 'User.count', -1 do
      u.destroy!
    end
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class GithubTokenTest < ActiveSupport::TestCase
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class AbuseCommentTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class PostCommentTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class APIKeyTest < ActiveSupport::TestCase
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class DomainGroupTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class PostTest < ActiveSupport::TestCase
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class ReviewQueueTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class UserSiteSettingTest < ActiveSupport::TestCase
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class APITokenTest < ActiveSupport::TestCase
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class ReasonTest < ActiveSupport::TestCase
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class SiteSettingTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class FlagSettingTest < ActiveSupport::TestCase
  test 'index notation should work' do
    key = FlagSetting.first.name
    assert FlagSetting[key] == FlagSetting.first.value
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class CommitStatusTest < ActiveSupport::TestCase
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class ChannelsUserTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class FlagConditionTest < ActiveSupport::TestCase
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class DomainLinkTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class DomainTagTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class ModeratorSiteTest < ActiveSupport::TestCase
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class ReviewResultTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class FeedbackTest < ActiveSupport::TestCase
  test 'should cache feedback' do
    p = Post.new link: '//stackoverflow.com/questions/1'
    p.title = 'A super title with description'
    p.save!

    refute p.is_tp
    refute p.is_fp

    f = Feedback.new
    f.post = p
    f.feedback_type = 'tpu-'
    f.save!

    assert p.is_tp
    refute p.is_fp

    f = Feedback.new
    f.post = p
    f.feedback_type = 'fpu-'
    f.save!

    assert p.is_tp
    assert p.is_fp
  end

  test 'should invalidate feedback cache' do
    p = Post.new link: '//stackoverflow.com/questions/1'
    p.title = 'A super title with description'
    p.save!

    true_feedback = Feedback.new
    true_feedback.post = p
    true_feedback.feedback_type = 'tpu-'
    true_feedback.save!

    false_feedback = Feedback.new
    false_feedback.post = p
    false_feedback.feedback_type = 'fpu-'
    false_feedback.save!

    true_feedback.is_invalidated = true
    true_feedback.save!

    refute p.is_tp
    assert p.is_fp

    false_feedback.is_invalidated = true
    false_feedback.save!

    refute p.is_tp
    refute p.is_fp
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class DeletionLogTest < ActiveSupport::TestCase
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class RoleTest < ActiveSupport::TestCase
  test 'names should be array of symbols' do
    assert Role.names.count > 0
    assert Role.names.select { |r| r.is_a? Symbol } == Role.names
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class FlagLogTest < ActiveSupport::TestCase
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class SpamWaveTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class DumpTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class QueryAverageTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class StatisticTest < ActiveSupport::TestCase
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class Emails::PreferenceTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class Emails::TypeTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class Emails::AddresseeTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class MetricsUpdateJobTest < ActiveJob::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class RedisLogJobTest < ActiveJob::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class AutoflagJobTest < ActiveJob::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class ScheduledMailJobTest < ActiveJob::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class ValidateFlagConditionForUserJobTest < ActiveJob::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

class ReasonsHelperTest < ActionView::TestCase
  test 'should check for inactive reasons' do
    ReasonsHelper.check_for_inactive_reasons
  end

  test 'should calculate weights for flagging' do
    ReasonsHelper.calculate_weights_for_flagging
  end
end


text:
# frozen_string_literal: true

class SitesHelperTest < ActionView::TestCase
  test 'should get new sites' do
    webmock_json_file = "#{Rails.root}/test/helpers/webmock_json_responses/sites_response.json"
    stub_request(:get, "https://api.stackexchange.com/2.2/sites?pagesize=1000&key=#{AppConfig['stack_exchange']['key']}&filter=!SmNndiHFp*Yrs)zUme")
      .to_return(status: 200, body: File.open(webmock_json_file).read, headers: {})

    SitesHelper.update_sites
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class DomainGroupsMailerTest < ActionMailer::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class AutoflaggingMailerTest < ActionMailer::TestCase
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class AnnouncementsMailerTest < ActionMailer::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

# Preview all emails at http://localhost:3000/rails/mailers/domain_groups_mailer
class DomainGroupsMailerPreview < ActionMailer::Preview
end


text:
# frozen_string_literal: true

# Preview all emails at http://localhost:3000/rails/mailers/announcements_mailer
class AnnouncementsMailerPreview < ActionMailer::Preview
end


text:
# frozen_string_literal: true

# Preview all emails at http://localhost:3000/rails/mailers/autoflagging_mailer
class AutoflaggingMailerPreview < ActionMailer::Preview
end


text:
# frozen_string_literal: true

require 'test_helper'

class AbuseReportStatusesControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class StackExchangeUsersControllerTest < ActionController::TestCase
  def setup
    @user = StackExchangeUser.last
  end

  test 'should mark user dead' do
    @user.update(still_alive: true)

    post :dead, params: { id: @user.id }
    assert_response 302 # 302 response because at least one diamond is required, which the test user doesn't have
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class AdminControllerTest < ActionController::TestCase
  test 'should get index' do
    sign_in users(:admin_user)
    get :index
    assert_response :success
  end

  test 'should get invalidated page' do
    sign_in users(:admin_user)

    get :recently_invalidated
    assert_response :success
  end

  test 'should get user feedback page' do
    sign_in users(:admin_user)

    get :user_feedback, params: { user_id: users(:approved_user).id }
    assert_response :success
    assert assigns(:feedback)
    assert assigns(:feedback_count)
    assert assigns(:invalid_count)
  end

  test 'should get users page' do
    sign_in users(:admin_user)
    get :users
    assert_response :success
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class StatisticsControllerTest < ActionDispatch::IntegrationTest
end


text:
# frozen_string_literal: true

require 'test_helper'

class ReasonsControllerTest < ActionController::TestCase
end


text:
# frozen_string_literal: true

require 'test_helper'

class DeveloperControllerTest < ActionDispatch::IntegrationTest
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class GraphsControllerTest < ActionController::TestCase
  test 'should get index' do
    get :index
    assert_response 200
  end

  test 'should get reports by hour' do
    get :reports_by_hour
    JSON.parse(response.body)
    assert_response 200
  end

  test 'should get reports by hour cached' do
    get :reports_by_hour, params: { cache: true }
    JSON.parse(response.body)
    assert_response 200
  end

  test 'should get reports by site' do
    get :reports_by_site, params: { timeframe: 'all' }
    JSON.parse(response.body)
    assert_response 200
  end

  test 'should get reports by hour of day' do
    get :reports_by_hour_of_day, params: { timeframe: 'all' }
    JSON.parse(response.body)
    assert_response 200
  end

  test 'should get time to deletion' do
    get :time_to_deletion
    JSON.parse(response.body)
    assert_response 200
  end

  test 'should get time to deletion cached' do
    get :time_to_deletion, params: { cache: true }
    JSON.parse(response.body)
    assert_response 200
  end

  test 'should get flagging results' do
    get :flagging_results
    JSON.parse(response.body)
    assert_response 200
  end

  test 'should get flagging results cached' do
    get :flagging_results, params: { cache: true }
    JSON.parse(response.body)
    assert_response 200
  end

  test 'should get flagging timeline' do
    get :flagging_timeline
    JSON.parse(response.body)
    assert_response 200
  end

  test 'should get flagging timeline cached' do
    get :flagging_timeline, params: { cache: true }
    JSON.parse(response.body)
    assert_response 200
  end

  test 'should get monthly TTD' do
    get :monthly_ttd
    JSON.parse(response.body)
    assert_response 200
  end

  test 'should get monthly TTD cached' do
    get :monthly_ttd, params: { cache: true }
    JSON.parse(response.body)
    assert_response 200
  end

  test 'should get monthly TTD for 1 month' do
    get :monthly_ttd, params: { months: 1 }
    JSON.parse(response.body)
    assert_response 200
  end

  test 'should get reports' do
    get :reports
    JSON.parse(response.body)
    assert_response 200
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class FeedbacksControllerTest < ActionController::TestCase
  test 'should allow admin to clear feedback' do
    sign_in users(:admin_user)

    get :clear, params: { id: Post.last.id }
    assert_response :success
  end

  test 'should not allow non-admins to clear feedback' do
    sign_out :user
    get :clear, params: { id: Post.last.id }
    assert_redirected_to new_user_session_url

    sign_in users(:approved_user)
    get :clear, params: { id: Post.last.id }
    assert_redirected_to missing_privileges_path(required: :admin)
  end

  test 'should mark cleared feedback invalidated' do
    sign_in users(:admin_user)
    delete :delete, params: { id: Feedback.last.id }
    assert Feedback.unscoped.last.is_invalidated?
  end

  test 'should not delete cleared feedback' do
    assert_no_difference 'Feedback.unscoped.count' do
      sign_in(:admin_user)
      delete :delete, params: { id: Feedback.last.id }
    end
  end

  test 'should redirect to clear page after deleting' do
    sign_in users(:admin_user)
    id = Feedback.last.id
    post_id = Feedback.last.post.id
    delete :delete, params: { id: id }
    assert_redirected_to clear_post_feedback_url(post_id)
  end

  test 'should attribute invalidations' do
    user = users(:admin_user)
    f_id = Feedback.last.id
    sign_in user

    delete :delete, params: { id: f_id }

    assert_equal Feedback.unscoped.find(f_id).invalidated_by, user
  end

  test 'should require smokedetector key to create feedback' do
    post :create, params: { feedback: {} }
    assert_response :forbidden

    post :create, params: { feedback: {}, key: 'wrongkey' }
    assert_response :forbidden
  end

  test 'should create feedback' do
    assert_difference ['Post.last.feedbacks.count', 'Feedback.count'] do
      post :create, params: {
        feedback: {
          message_link: 'foo',
          user_name: 'Undo',
          user_link: 'http://foo.bar/undo',
          feedback_type: 'tpu-',
          post_link: Post.last.link,
          chat_user: 12_345
        },
        key: SmokeDetector.last.access_token
      }
    end
  end

  test 'should ignore identical feedback from the same user' do
    # assert_difference looks for a delta of 1; a delta of 2 would error out
    assert_difference ['Post.last.feedbacks.count', 'Feedback.count'] do
      3.times do
        post :create, params: {
          feedback: {
            message_link: 'foo',
            user_name: 'Undo',
            user_link: 'http://foo.bar/undo',
            feedback_type: 'tpu-',
            post_link: Post.last.link,
            chat_user: 12_345
          },
          key: SmokeDetector.last.access_token
        }
      end
    end
  end

  test 'should remove old feedback from the same user' do
    Post.last.feedbacks.destroy_all

    assert_difference ['Post.last.feedbacks.count', 'Feedback.count'] do
      ['tpu-', 'fpu-'].each do |feedback_type|
        post :create, params: {
          feedback: {
            message_link: 'foo',
            user_name: 'Undo',
            user_link: 'http://foo.bar/undo',
            feedback_type: feedback_type,
            post_link: Post.last.link,
            chat_user: 12_345
          },
          key: SmokeDetector.last.access_token
        }
      end
    end
  end

  test 'should cache feedback' do
    p = Post.where(is_tp: false).last

    post :create, params: {
      feedback: {
        message_link: 'foo',
        user_name: 'Undo',
        user_link: 'http://foo.bar/undo',
        feedback_type: 'tpu-',
        post_link: p.link,
        chat_user: 12_345
      },
      key: SmokeDetector.last.access_token
    }

    assert Post.find(p.id).is_tp

    p = Post.where(is_fp: false).last

    post :create, params: {
      feedback: {
        message_link: 'foo',
        user_name: 'Undo',
        user_link: 'http://foo.bar/undo',
        feedback_type: 'fpu-',
        post_link: p.link,
        chat_user: 12_345
      },
      key: SmokeDetector.last.access_token
    }

    assert Post.find(p.id).is_fp
  end

  test 'should destroy previous feedback from user created within 24 hours' do
    p = Post.last
    p.feedbacks.delete_all

    user_id = User.last.id

    f1 = p.feedbacks.create(user_id: user_id, feedback_type: 'tpu-')

    assert p.feedbacks.count == 1

    assert_no_difference 'p.feedbacks.count' do
      f2 = f1.dup
      f2.feedback_type = 'fpu-'
      f2.save
    end
  end

  test "shouldn't destroy other user's previous feedback" do
    p = Post.last
    p.feedbacks.delete_all

    f1 = p.feedbacks.create(user_id: User.first.id, feedback_type: 'tpu-')

    f1_other_user = f1.dup
    f1_other_user.user_id = User.last.id
    f1_other_user.save

    assert p.feedbacks.count == 2

    assert_no_difference 'p.feedbacks.count' do
      f2 = f1.dup
      f2.feedback_type = 'fpu-'
      f2.save
    end
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class DomainTagsControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class UsersControllerTest < ActionController::TestCase
  test 'should get apps list' do
    sign_in users(:approved_user)
    get :apps
    assert_response(200)
  end

  test 'should revoke app access' do
    sign_in users(:approved_user)
    before_test_count = APIToken.count
    delete :revoke_app, params: { key_id: api_keys(:one).id }
    assert_response(302)
    assert_nil flash[:danger]
    assert_operator before_test_count, :>, APIToken.count
  end

  test 'should get two-factor status page' do
    sign_in users(:approved_user)
    get :tf_status
    assert_response 200
  end

  test 'should add a secret to the account' do
    sign_in users(:approved_user)
    post :enable_2fa
    users(:approved_user).reload
    assert_response 200
    assert_not_nil assigns(:qr_uri)
    assert_not_nil users(:approved_user).two_factor_token
  end

  test 'should get enable code confirmation page' do
    sign_in users(:approved_user)
    get :enable_code
    assert_response 200
  end

  test 'should confirm enable code' do
    sign_in users(:two_factor_confirming)
    totp = ROTP::TOTP.new(users(:two_factor_confirming).two_factor_token)
    post :confirm_enable_code, params: { code: totp.now }
    users(:two_factor_confirming).reload
    assert_nil flash[:danger]
    assert_not_nil flash[:success]
    assert_equal true, users(:two_factor_confirming).enabled_2fa
    assert_response 302
  end

  test 'should get disable code confirmation page' do
    sign_in users(:two_factor_full)
    get :disable_code
    assert_response 200
  end

  test 'should confirm disable code' do
    sign_in users(:two_factor_full)
    totp = ROTP::TOTP.new(users(:two_factor_full).two_factor_token)
    post :confirm_disable_code, params: { code: totp.now }
    users(:two_factor_full).reload
    assert_nil flash[:danger]
    assert_not_nil flash[:success]
    assert_equal false, users(:two_factor_full).enabled_2fa
    assert_nil users(:two_factor_full).two_factor_token
    assert_response 302
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class CustomSessionsControllerTest < ActionDispatch::IntegrationTest
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class SpamDomainsControllerTest < ActionController::TestCase
  test 'should get index' do
    get :index
    assert_not_nil assigns(:total)
    assert_not_nil assigns(:domains)
    assert_response :success
  end

  test 'should deny create to non-smokey clients' do
    post :create_from_post
    assert_response :forbidden
  end

  test 'should let smokey create spam domains' do
    post :create_from_post, params: { key: smoke_detectors(:smoke_detector_1).access_token, post_id: posts(:post_23601).id,
                                      domains: ['test.spam.com'] }
    assert_equal({ 'status' => 'success', 'total_domains' => 1 }, JSON.parse(response.body))
    assert_response :success
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class DeletionLogsControllerTest < ActionDispatch::IntegrationTest
  test 'should require smokedetector key to create deletion log' do
    post '/deletion_logs.json', params: { post: {} }
    assert_response :forbidden

    post '/deletion_logs.json', params: { post: {}, key: 'wrongkey' }
    assert_response :forbidden
  end

  test 'should create deletion log' do
    assert_difference ['DeletionLog.count', 'Post.last.deletion_logs.count'] do
      post '/deletion_logs.json', params: { deletion_log: { is_deleted: true, post_link: Post.last.link }, key: SmokeDetector.first.access_token }
    end
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class StatusControllerTest < ActionController::TestCase
  def setup
    @smoke_detector = SmokeDetector.order(:last_ping).last
  end

  test 'should get index' do
    [0, 2, 10].each do |m|
      @smoke_detector.update(last_ping: m.minutes.ago)
      get :index
      assert_response :success
    end
  end

  test 'should update last-seen time on status ping' do
    post :status_update, params: { key: @smoke_detector.access_token, location: @smoke_detector.location }
    assert_in_delta Time.now.to_i, @smoke_detector.reload.last_ping.to_i, 2
  end

  test 'should failover' do
    SmokeDetector.update_all(is_standby: true)

    post :status_update, params: { key: @smoke_detector.access_token, location: @smoke_detector.location }
    assert_equal false, @smoke_detector.is_standby
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class FlagSettingsControllerTest < ActionDispatch::IntegrationTest
  include Devise::Test::IntegrationHelpers
  setup do
    @flag_setting = FlagSetting.first
  end

  test 'should get index' do
    get flag_settings_url
    assert_response :success
  end

  test 'should get new' do
    sign_out :user
    get new_flag_setting_path
    assert_redirected_to missing_privileges_path(required: :admin)

    sign_in users(:admin_user)
    get new_flag_setting_path

    assert_response :success
  end

  test 'should create flag_setting' do
    sign_out :user

    post flag_settings_url, params: { flag_setting: { name: @flag_setting.name, value: @flag_setting.value } }
    assert_redirected_to missing_privileges_path(required: :admin)

    sign_in users(:admin_user)

    assert_difference('FlagSetting.count') do
      post flag_settings_url, params: { flag_setting: { name: 'such valid', value: 'very setting' } }
    end

    assert_redirected_to flag_settings_path
  end

  test 'should get edit' do
    sign_out :user

    get edit_flag_setting_url(@flag_setting)
    assert_redirected_to missing_privileges_path(required: :admin)

    sign_in users(:admin_user)

    get edit_flag_setting_url(@flag_setting)
    assert_response :success
  end

  test 'should update flag_setting' do
    sign_out :user

    patch flag_setting_url(@flag_setting), params: { flag_setting: { name: @flag_setting.name, value: @flag_setting.value } }
    assert_redirected_to missing_privileges_path(required: :admin)

    sign_in users(:admin_user)

    patch flag_setting_url(@flag_setting), params: { flag_setting: { name: 'valid', value: 'also valid' } }
    assert_redirected_to flag_settings_path
  end

  test 'should get audit log' do
    sign_out :user

    get flag_settings_audits_url

    assert_response :success
  end

  test 'should get dashboard' do
    sign_out :user
    get flagging_url
    assert_response :success

    sign_in users(:admin_user)
    get flagging_url
    assert_response :success
  end

  test 'should allow smokey to disable flagging' do
    sign_out :user
    post smokey_disable_url, params: { key: SmokeDetector.first.access_token }

    # Should disable flagging
    assert FlagSetting['flagging_enabled'] == '0'

    # Should be recorded as System having done it
    assert FlagSetting.find_by(name: 'flagging_enabled').audits.last.user_id == -1
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class SiteSettingsControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class DomainGroupsControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class FlagLogControllerTest < ActionDispatch::IntegrationTest
end


text:
# frozen_string_literal: true

require 'test_helper'

class SearchControllerTest < ActionController::TestCase
  test 'should get index' do
    get :index
    assert_response :success
    assert_not_nil assigns(:results)
  end

  test 'should search by site' do
    site = Post.last.site

    get :index, params: { site: site.site_name }
    assert_response :success
    assert_not_nil assigns(:results)
    assert_equal(assigns(:results), assigns(:results).select { |p| p.site_id == site.id })
  end

  test 'should search by reputation' do
    get :index, params: { user_rep_direction: '>=', user_reputation: 10 }
    assert_response :success
    assert_not_nil assigns(:results)
    assert_equal(assigns(:results), assigns(:results).select { |p| p.user_reputation >= 10 })
  end

  test 'should search by reputation with graph' do
    get :index, params: { user_rep_direction: '>=', user_reputation: 10, option: 'graph' }
    assert_response :success
    assert_not_nil assigns(:results)
    assert_equal(assigns(:results), assigns(:results).select { |p| p.user_reputation >= 10 })
  end

  test 'should search by false positive' do
    get :index, params: { feedback: 'false positive' }
    assert_response :success
  end

  test 'should search by false positive with graph' do
    get :index, params: { feedback: 'false positive', option: 'graph' }
    assert_response :success
  end

  test 'should search by regex' do
    sign_in User.first

    get :index, params: { title: 'foo', title_is_regex: true, title_is_inverse_regex: true }
    assert_response :success
  end

  test 'should search by not autoflagged' do
    get :index, params: { autoflagged: 'No' }
    assert_response :success
    assert_not_nil assigns(:results)
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class AbuseCommentsControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class DataControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class APIKeysControllerTest < ActionController::TestCase
  test 'should get index' do
    sign_in users(:admin_user)
    get :index
    assert_response(200)
  end

  test 'should get new' do
    sign_in users(:admin_user)
    get :new
    assert_response(200)
  end

  test 'should create new key' do
    sign_in users(:admin_user)
    post :create, params: { api_key: { key: '71ab6e12d4287e6d1cd6549f039e46646ae379a709bd359e9231a385e5ff970f', app_name: 'new_tests' } }
    assert_response(302)
  end

  test 'should revoke write tokens' do
    sign_in users(:admin_user)
    before_test_count = APIToken.count

    delete :revoke_write_tokens, params: { id: api_keys(:one).id }
    assert_response(302)

    # Assert that the count before the test is more than the count
    # after the test; i.e. some tokens disappeared
    assert_operator before_test_count, :>, APIToken.count
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class PostCommentsControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class SpamWavesControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class PostsControllerTest < ActionController::TestCase
  def setup
    @posts = Post.all
    @single_post = Post.last
  end

  test 'should get index' do
    get :index
    assert_response :success
    assert_not_nil assigns(:posts)
  end

  test 'should show post' do
    @posts.each do |post|
      get :show, params: { id: post.id }
      assert_response :success
      assert_not_nil assigns(:post)
    end
  end

  test 'should show posts to signed-in users' do
    sign_in users(:admin_user)
    @posts.each do |post|
      get :show, params: { id: post.id }
      assert_response :success
      assert_not_nil assigns(:post)
    end
  end

  test 'should require smokedetector key to create post' do
    post :create, params: { post: {} }
    assert_response :forbidden

    post :create, params: { post: {}, key: 'wrongkey' }
    assert_response :forbidden
  end

  test 'should create post' do
    assert_difference 'Post.count' do
      post :create, params: {
        post: {
          title: 'Test Post Title',
          body: 'Awesome Post Body',
          link: '//stackoverflow.com/questions/1',
          username: 'Undo',
          user_reputation: 101,
          user_link: '//stackoverflow.com/users/1849664/undo',
          why: 'Some why data',
          reasons: ['Bad keyword in body']
        },
        key: SmokeDetector.first.access_token
      }

      assert_response :success
    end
  end

  test 'should quietly reject recent duplicates from other instances as 200 Duplicate Report' do
    post :create, params: {
      post: {
        title: 'blah blah blah',
        body: 'blah blah',
        link: '//stackoverflow.com/questions/1234',
        username: 'Undo',
        user_reputation: 101,
        user_link: '//stackoverflow.com/users/123',
        why: 'Some why data',
        reasons: ['Bad keyword in body']
      },
      key: SmokeDetector.first.access_token
    }

    assert_no_difference 'Post.count' do
      post :create, params: {
        post: {
          title: 'blah blah blah',
          body: 'blah blah',
          link: '//stackoverflow.com/questions/1234',
          username: 'Undo',
          user_reputation: 101,
          user_link: '//stackoverflow.com/users/123',
          why: 'Some why data',
          reasons: ['Bad keyword in body']
        },
        key: SmokeDetector.last.access_token
      }

      assert_response(200, 'Duplicate Report')
    end
  end

  test 'should quietly reject duplicate posts from same instance as 200 Duplicate Report' do
    post :create, params: {
      post: {
        title: 'blah blah blah',
        body: 'blah blah',
        link: '//stackoverflow.com/questions/1234',
        username: 'Undo',
        user_reputation: 101,
        user_link: '//stackoverflow.com/users/123',
        why: 'Some why data',
        reasons: ['Bad keyword in body']
      },
      key: SmokeDetector.first.access_token
    }

    assert_no_difference 'Post.count' do
      post :create, params: {
        post: {
          title: 'blah blah blah',
          body: 'blah blah',
          link: '//stackoverflow.com/questions/1234',
          username: 'Undo',
          user_reputation: 101,
          user_link: '//stackoverflow.com/users/123',
          why: 'Some why data',
          reasons: ['Bad keyword in body']
        },
        key: SmokeDetector.first.access_token
      }

      assert_response(200, 'Duplicate Report')
    end
  end

  test 'should not reject near-duplicate posts with different title' do
    post :create, params: {
      post: {
        title: 'blah blah blah',
        body: 'blah blah',
        link: '//stackoverflow.com/questions/1234',
        username: 'Undo',
        user_reputation: 101,
        user_link: '//stackoverflow.com/users/123',
        why: 'Some why data',
        reasons: ['Bad keyword in body']
      },
      key: SmokeDetector.first.access_token
    }

    assert_difference 'Post.count' do
      post :create, params: {
        post: {
          title: 'blah blah diff',
          body: 'blah blah',
          link: '//stackoverflow.com/questions/1234',
          username: 'Undo',
          user_reputation: 101,
          user_link: '//stackoverflow.com/users/123',
          why: 'Some why data',
          reasons: ['Bad keyword in body']
        },
        key: SmokeDetector.first.access_token
      }

      assert_response(201, 'OK')
    end
  end

  test 'should not reject near-duplicate posts with different body' do
    post :create, params: {
      post: {
        title: 'blah blah blah',
        body: 'blah blah',
        link: '//stackoverflow.com/questions/1234',
        username: 'Undo',
        user_reputation: 101,
        user_link: '//stackoverflow.com/users/123',
        why: 'Some why data',
        reasons: ['Bad keyword in body']
      },
      key: SmokeDetector.first.access_token
    }

    assert_difference 'Post.count' do
      post :create, params: {
        post: {
          title: 'blah blah blah',
          body: 'blah diff',
          link: '//stackoverflow.com/questions/1234',
          username: 'Undo',
          user_reputation: 101,
          user_link: '//stackoverflow.com/users/123',
          why: 'Some why data',
          reasons: ['Bad keyword in body']
        },
        key: SmokeDetector.first.access_token
      }

      assert_response(201, 'OK')
    end
  end

  test 'should not reject near-duplicate posts with different username' do
    post :create, params: {
      post: {
        title: 'blah blah blah',
        body: 'blah blah',
        link: '//stackoverflow.com/questions/1234',
        username: 'Redo',
        user_reputation: 101,
        user_link: '//stackoverflow.com/users/123',
        why: 'Some why data',
        reasons: ['Bad keyword in body']
      },
      key: SmokeDetector.first.access_token
    }

    assert_difference 'Post.count' do
      post :create, params: {
        post: {
          title: 'blah blah blah',
          body: 'blah blah',
          link: '//stackoverflow.com/questions/1234',
          username: 'Undo',
          user_reputation: 101,
          user_link: '//stackoverflow.com/users/123',
          why: 'Some why data',
          reasons: ['Bad keyword in body']
        },
        key: SmokeDetector.first.access_token
      }

      assert_response(201, 'OK')
    end
  end

  test 'should not reject near-duplicate posts with different why' do
    post :create, params: {
      post: {
        title: 'blah blah blah',
        body: 'blah blah',
        link: '//stackoverflow.com/questions/1234',
        username: 'Undo',
        user_reputation: 101,
        user_link: '//stackoverflow.com/users/123',
        why: 'Some why data',
        reasons: ['Bad keyword in body']
      },
      key: SmokeDetector.first.access_token
    }

    assert_difference 'Post.count' do
      post :create, params: {
        post: {
          title: 'blah blah blah',
          body: 'blah blah',
          link: '//stackoverflow.com/questions/1234',
          username: 'Undo',
          user_reputation: 101,
          user_link: '//stackoverflow.com/users/123',
          why: 'Some why diff',
          reasons: ['Bad keyword in body']
        },
        key: SmokeDetector.first.access_token
      }

      assert_response(201, 'OK')
    end
  end

  test 'should not reject near-duplicate posts with different link' do
    post :create, params: {
      post: {
        title: 'blah blah blah',
        body: 'blah blah',
        link: '//stackoverflow.com/questions/1234',
        username: 'Undo',
        user_reputation: 101,
        user_link: '//stackoverflow.com/users/123',
        why: 'Some why data',
        reasons: ['Bad keyword in body']
      },
      key: SmokeDetector.first.access_token
    }

    assert_difference 'Post.count' do
      post :create, params: {
        post: {
          title: 'blah blah blah',
          body: 'blah blah',
          link: '//stackoverflow.com/questions/1235',
          username: 'Undo',
          user_reputation: 101,
          user_link: '//stackoverflow.com/users/123',
          why: 'Some why data',
          reasons: ['Bad keyword in body']
        },
        key: SmokeDetector.first.access_token
      }

      assert_response(201, 'OK')
    end
  end

  test 'should create new reason' do
    assert_difference 'Reason.count' do
      post :create, params: {
        post: {
          title: 'Test Post Title',
          body: 'Awesome Post Body',
          link: '//stackoverflow.com/questions/1',
          username: 'Undo',
          user_reputation: 101,
          user_link: '//stackoverflow.com/users/1849664/undo',
          reasons: ['Brand new reason']
        },
        key: SmokeDetector.first.access_token
      }

      assert_response :success
    end
  end

  test 'should lazy-load post body' do
    get :body, params: { id: Post.last.id }
    assert_response 200
    assert assigns(:post)
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class DomainLinksControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class DashboardControllerTest < ActionController::TestCase
  test 'should work for anonymous users' do
    get :new_dash
    assert_response :success
  end

  test 'should work for flaggers' do
    sign_in users(:unapproved_user)
    get :new_dash
    assert_response :success
  end

  test 'should work for reviewers' do
    sign_in users(:approved_user)
    get :new_dash
    assert_response :success
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class ReviewQueuesControllerTest < ActionController::TestCase
  test 'should get index' do
    sign_in users(:approved_user)
    get :index
    assert_response :success
    assert_not_nil assigns(:queues)
  end

  test 'should get posts review' do
    sign_in users(:approved_user)
    get :queue, params: { name: 'posts' }
    assert_response :success
    assert_not_nil assigns(:queue)
  end

  test 'should get next posts queue item' do
    sign_in users(:approved_user)
    get :next_item, params: { name: 'posts' }
    assert_response :success
  end

  test 'should submit result' do
    sign_in users(:approved_user)
    post :submit, params: { name: 'posts', item_id: review_items(:one), response: 'tp' }
    assert_response :success
    assert_equal 'ok', JSON.parse(@response.body)['status']
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class CustomRegistrationsControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class MicroAuthControllerTest < ActionController::TestCase
  test 'should get token request' do
    sign_in users(:approved_user)
    get :token_request, params: { key: api_keys(:one).key }
    assert_response(200)
  end

  test 'should authorize app' do
    sign_in users(:approved_user)
    post :authorize, params: { key: api_keys(:one).key }
    assert_nil flash[:danger]
    assert_response(302)
  end

  test 'should get authorized' do
    sign_in users(:approved_user)
    get :authorized, params: { token_id: api_tokens(:one).id, code: api_tokens(:one).code }
    assert_response(200)
  end

  test 'should get reject' do
    sign_in users(:approved_user)
    get :reject, params: { key: api_keys(:one).key }
    assert_response(200)
  end

  test 'should get invalid key' do
    sign_in users(:approved_user)
    get :invalid_key
    assert_response(200)
  end

  test 'should get token' do
    sign_out :user
    get :token, params: { code: api_tokens(:one).code, key: api_keys(:one).key }
    assert_equal api_tokens(:one).token, JSON.parse(@response.body)['token']
  end

  test 'should run whole auth cycle' do
    sign_in users(:approved_user)
    get :token_request, params: { key: api_keys(:one).key }
    post :authorize, params: { key: api_keys(:one).key }

    token = assigns(:token)

    sign_out :user
    get :token, params: { code: token.code, key: api_keys(:one).key }

    assert_equal token.token, JSON.parse(@response.body)['token']
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class UserSiteSettingsControllerTest < ActionController::TestCase
  test 'should list my preferences' do
    sign_in users(:approved_user)
    get :index

    assert_not_nil assigns(:preferences)
    assert_response 200
  end

  test 'should list another users preferences' do
    sign_in users(:approved_user)
    get :for_user, params: { user: users(:approved_user).id }
    assert_redirected_to missing_privileges_path(required: :admin)

    sign_out :user
    sign_in users(:admin_user)
    get :for_user, params: { user: users(:approved_user).id }

    assert_not_nil assigns(:preferences)
    assert_not_nil assigns(:user)
    assert_equal users(:approved_user).id, assigns(:user).id
    assert_response 200
  end

  test 'should enable flagging' do
    sign_in users(:approved_user)
    users(:approved_user).add_role :flagger
    post :enable_flagging, params: { enable: true }

    assert_equal 'ok', JSON.parse(response.body)['status']
    assert_response 200
  end

  test 'should get new' do
    sign_in users(:approved_user)
    get :new

    assert_not_nil assigns(:preference)
    assert_response 200
  end

  test 'should create preference' do
    sign_in users(:approved_user)

    assert_difference 'UserSiteSetting.count' do
      post :create, params: { user_site_setting: { max_flags: 10, sites: [sites(:Site_1).id] } }
    end

    assert_not_nil assigns(:preference)
    assert_response 302
  end

  test 'should refuse to create preference with no sites' do
    sign_in users(:approved_user)
    post :create, params: { user_site_setting: { max_flags: 10, sites: [] } }

    assert_response 422
  end

  test 'should get edit' do
    sign_in users(:approved_user)
    get :edit, params: { id: user_site_settings(:one).id }

    assert_not_nil assigns(:preference)
    assert_response 200
  end

  test 'should update preference' do
    sign_in users(:approved_user)
    patch :update, params: { user_site_setting: { max_flags: 11, sites: [sites(:Site_1).id] }, id: user_site_settings(:one).id }

    assert_not_nil assigns(:preference)
    assert_response 302
  end

  test 'should destroy preference' do
    sign_in users(:approved_user)

    assert_difference 'UserSiteSetting.count', -1 do
      delete :destroy, params: { id: user_site_settings(:one).id }
    end

    assert_not_nil assigns(:preference)
    assert_response 302
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class RSSControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class SmokeDetectorsControllerTest < ActionDispatch::IntegrationTest
  # test 'the truth' do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class APIControllerTest < ActionController::TestCase
  test 'should get index' do
    sign_out(:users)
    get :api_docs

    assert_response 302
  end

  # Hopefully at some point I will write tests for V2. (Ha!)
end


text:
# frozen_string_literal: true

require 'test_helper'

class AuthenticationControllerTest < ActionDispatch::IntegrationTest
end


text:
# frozen_string_literal: true

require 'test_helper'

class AbuseReportsControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class AnnouncementsControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class AbuseContactsControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end


text:
# frozen_string_literal: true

require 'test_helper'

class FlagConditionsControllerTest < ActionController::TestCase
  test 'should list my flag conditions' do
    sign_in users(:approved_user)
    get :index

    assert_not_nil assigns(:conditions)
    assert_response 200
  end

  test 'should list all flag conditions' do
    sign_in users(:approved_user)

    get :full_list
    assert_redirected_to missing_privileges_path(required: :admin)

    sign_out :user
    sign_in users(:admin_user)
    get :full_list

    assert_not_nil assigns(:conditions)
    assert_equal FlagCondition.count, assigns(:conditions).count
    assert_response 200
  end

  test 'should create new flag condition' do
    sign_in users(:approved_user)

    assert_difference 'FlagCondition.count' do
      post :create, params: {
        flag_condition: {
          min_weight: 300,
          max_poster_rep: 10,
          min_reason_count: 4,
          sites: [sites(:Site_1).id, sites(:Site_2).id]
        }
      }
    end

    assert_not_nil assigns(:condition)
    assert_response 302
  end

  test 'should get edit' do
    sign_in users(:approved_user)
    get :edit, params: { id: FlagCondition.last.id, flag_condition: { sites: [Site.last.id] } }

    assert_not_nil assigns(:condition)
    assert_response 200
  end

  test 'should update flag condition' do
    sign_in users(:approved_user)
    patch :update, params: {
      flag_condition: {
        min_weight: 301,
        max_poster_rep: 11,
        min_reason_count: 5,
        sites: [sites(:Site_1).id]
      },
      id: FlagCondition.last.id
    }

    assert_not_nil assigns(:condition)
    assert_response 302
  end

  test 'should destroy flag condition' do
    sign_in users(:approved_user)

    assert_difference 'FlagCondition.count', -1 do
      delete :destroy, params: { id: FlagCondition.last.id }
    end
    assert_not_nil assigns(:condition)
    assert_response 302
  end
end


text:
# frozen_string_literal: true

require 'test_helper'

class Emails::PreferencesControllerTest < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end


text:
smoke_detector_1:
  id: 1
  last_ping: !ruby/object:ActiveSupport::TimeWithZone
    utc: &1 2016-04-02 12:59:44.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *1
  name:
  location: Raspberry Pi
  access_token: NFr1c7hRVkyocO6vearZ9plq2CllpNz1Z0kj2Q3G
  created_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &2 2016-02-20 23:25:32.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *2
  updated_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &3 2016-04-02 12:59:44.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *3
  email_date: !ruby/object:ActiveSupport::TimeWithZone
    utc: &4 2016-03-28 18:52:13.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *4
  user_id: -1

smoke_detector_2:
  id: 2
  last_ping: !ruby/object:ActiveSupport::TimeWithZone
    utc: &1 2016-04-02 12:59:44.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *1
  name:
  location: Raspberry Pi 2
  access_token: NFr1c7hRVkyocO6vearZ9plq2CllpNz1Z0kj2Q3G2
  created_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &2 2016-02-20 23:25:32.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *2
  updated_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &3 2016-04-02 12:59:44.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *3
  email_date: !ruby/object:ActiveSupport::TimeWithZone
    utc: &4 2016-03-28 18:52:13.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *4
  user_id: -1


text:
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
  post: one
  user: one
  text: MyText

two:
  post: two
  user: two
  text: MyText


text:
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
  user_id: 1
  site_id: 1

two:
  user_id: 1
  site_id: 1


text:
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
  reason: MyString
  user_id: MyString

two:
  reason: MyString
  user_id: MyString


text:
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
  code: deadbee
  api_key: one
  user: approved_user
  token: ad522fb97c4e8ce6891edf74e5242f53dbc169a05779315da8952cb269874dac
  expiry: <%= 1.month.from_now.strftime("%Y-%m-%d") %>


text:
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
  user: one
  secret: MyString
  link: MyString

two:
  user: two
  secret: MyString
  link: MyString


text:
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

posts:
  name: posts
  privileges: reviewer
  reviewable_type: Post
  responses: '[["True Positive", "tp"]]'


text:
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
  posts_scanned:

two:
  posts_scanned:


text:
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

# This model initially had no columns defined.  If you add columns to the
# model remove the '{}' from the fixture names and add the columns immediately
# below each fixture, per the syntax in the comments below
#

feedback_19114:
  id: 19114
  message_link:
  user_name:
  user_link:
  feedback_type: fp
  post_id: 1
  post_link:
  user_id: 7
  is_invalidated: false

feedback_23950:
  id: 23950
  message_link:
  user_name:
  user_link:
  feedback_type: fp
  post_id: 2
  post_link:
  user_id: 7
  is_invalidated: false

feedback_21549:
  id: 21549
  message_link:
  user_name:
  user_link:
  feedback_type: tp
  post_id: 3
  post_link:
  user_id: 3
  is_invalidated: false

feedback_22636:
  id: 22636
  message_link:
  user_name:
  user_link:
  feedback_type: tp
  post_id: 4
  post_link:
  user_id: 3
  is_invalidated: false

feedback_21550:
  id: 21550
  message_link:
  user_name:
  user_link:
  feedback_type: tp
  post_id: 5
  post_link:
  user_id: 3
  is_invalidated: false

feedback_25039:
  id: 25039
  message_link:
  user_name: System (Undo)
  user_link:
  feedback_type: Ambiguous
  post_id: 6
  post_link:
  user_id:
  is_invalidated: false

feedback_19052:
  id: 19052
  message_link:
  user_name:
  user_link:
  feedback_type: tp
  post_id: 7
  post_link:
  user_id: 1
  is_invalidated: false

feedback_22637:
  id: 22637
  message_link:
  user_name:
  user_link:
  feedback_type: tp
  post_id: 8
  post_link:
  user_id: 3
  is_invalidated: false

feedback_19053:
  id: 19053
  message_link:
  user_name:
  user_link:
  feedback_type: tp
  post_id: 9
  post_link:
  user_id: 1
  is_invalidated: false

feedback_19054:
  id: 19054
  message_link:
  user_name:
  user_link:
  feedback_type: tp
  post_id: 10
  post_link:
  user_id: 1
  is_invalidated: false

feedback_29653:
  id: 29653
  message_link:
  user_name: Ferrybig
  user_link:
  feedback_type: tpu-
  post_id: 23653
  post_link: "//askubuntu.com/questions/752989"
  user_id:
  is_invalidated: false

feedback_29652:
  id: 29652
  message_link:
  user_name: Ferrybig
  user_link:
  feedback_type: tpu-
  post_id: 23654
  post_link: "//meta.stackexchange.com/questions/277856"
  user_id:
  is_invalidated: false

feedback_29651:
  id: 29651
  message_link:
  user_name: Ferrybig
  user_link:
  feedback_type: tpu-
  post_id: 23655
  post_link: "//stackoverflow.com/questions/36372314"
  user_id:
  is_invalidated: false

feedback_29655:
  id: 29655
  message_link:
  user_name: Ferrybig
  user_link:
  feedback_type: tpu-
  post_id: 23656
  post_link: "//stackoverflow.com/questions/36372575"
  user_id:
  is_invalidated: false

feedback_29656:
  id: 29656
  message_link:
  user_name: Ferrybig
  user_link:
  feedback_type: tpu-
  post_id: 23657
  post_link: "//stackoverflow.com/a/36372816"
  user_id:
  is_invalidated: false

feedback_29657:
  id: 29657
  message_link:
  user_name: Ferrybig
  user_link:
  feedback_type: tpu-
  post_id: 23658
  post_link: "//stackoverflow.com/a/36372990"
  user_id:
  is_invalidated: false

feedback_29658:
  id: 29658
  message_link:
  user_name: Ferrybig
  user_link:
  feedback_type: fp-
  post_id: 23659
  post_link: "//diy.stackexchange.com/a/87919"
  user_id:
  is_invalidated: false

feedback_29660:
  id: 29660
  message_link:
  user_name: Ferrybig
  user_link:
  feedback_type: tpu-
  post_id: 23660
  post_link: "//webapps.stackexchange.com/a/91488"
  user_id:
  is_invalidated: false

feedback_29661:
  id: 29661
  message_link:
  user_name: Ferrybig
  user_link:
  feedback_type: tpu-
  post_id: 23661
  post_link: "//money.stackexchange.com/questions/62365"
  user_id:
  is_invalidated: false

feedback_29663:
  id: 29663
  message_link:
  user_name: Unikitty Blends People
  user_link:
  feedback_type: tpu-
  post_id: 23661
  post_link: "//money.stackexchange.com/questions/62365"
  user_id:
  is_invalidated: false


text:
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

enabled:
  name: flagging_enabled
  value: 1

registration:
  name: registration_enabled
  value: 1

max_flags:
  name: max_flags
  value: 3

dry_run:
  name: dry_run
  value: 0

scaled_max_flags:
  name: scaled_max_flags
  value: 0,0,0,99.9,99.99,101


text:
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
  text: MyString
  expiry: 2017-06-05 12:09:06

two:
  text: MyString
  expiry: 2017-06-05 12:09:06


text:
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
  flags_enabled: false
  min_weight: 1
  max_poster_rep: 1
  min_reason_count: 1
  user: approved_user

two:
  flags_enabled: false
  min_weight: 1
  max_poster_rep: 1
  min_reason_count: 1
  user: approved_user


text:
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
  left_id:
  right_id:
  link_type: MyString
  comments: MyText
  creator:

two:
  left_id:
  right_id:
  link_type: MyString
  comments: MyText
  creator:


text:
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
  token: MyString
  expires: 2016-12-21 11:16:11

two:
  token: MyString
  expires: 2016-12-21 11:16:11


text:
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

# This model initially had no columns defined.  If you add columns to the
# model remove the '{}' from the fixture names and add the columns immediately
# below each fixture, per the syntax in the comments below
#

system_user:
  email: foo@bar.com
  encrypted_password: "abcdefghjklmnopqrstuvwxyz3"
  remember_created_at:
  created_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &3 2015-08-23 23:29:39.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *3
  updated_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &4 2016-03-31 15:09:34.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *4
  reset_password_token: abcdefghijklmnopqrstuvwxyz3
  reset_password_sent_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &5 2016-03-16 19:42:53.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *5
  roles: reviewer, blacklist_manager
  id: -1

approved_user:
  email: approved@user.com
  encrypted_password: "abcdefghjklmnopqrstuvwxyz"
  remember_created_at:
  created_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &3 2015-08-23 23:29:39.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *3
  updated_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &4 2016-03-31 15:09:34.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *4
  reset_password_token: abcdefghijklmnopqrstuvwxyz
  reset_password_sent_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &5 2016-03-16 19:42:53.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *5
  roles: reviewer, flagger
  stack_exchange_account_id: 4606062

unapproved_user:
  email: unapproved@user.com
  encrypted_password: "abcdefghjklmnopqrstuvwxyz"
  remember_created_at:
  created_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &3 2015-08-23 23:29:39.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *3
  updated_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &4 2016-03-31 15:09:34.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *4
  reset_password_token: abcdefghijklmnopqrstuvwxyz1
  reset_password_sent_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &5 2016-03-16 19:42:53.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *5
  roles: flagger

admin_user:
  email: admin@user.com
  encrypted_password: "abcdefghjklmnopqrstuvwxyz3"
  remember_created_at:
  created_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &3 2015-08-23 23:29:39.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *3
  updated_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &4 2016-03-31 15:09:34.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *4
  reset_password_token: abcdefghijklmnopqrstuvwxyz3
  reset_password_sent_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &5 2016-03-16 19:42:53.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *5
  roles: reviewer, admin

code_admin_user:
  email: code_admin@user.com
  encrypted_password: "abcdefghjklmnopqrstuvwxyz3"
  remember_created_at:
  created_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &3 2015-08-23 23:29:39.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *3
  updated_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &4 2016-03-31 15:09:34.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *4
  reset_password_token: abcdefghijklmnopqrstuvwxyz3
  reset_password_sent_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &5 2016-03-16 19:42:53.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *5
  roles: reviewer, blacklist_manager

two_factor_confirming:
  email: two_factor@user.com
  encrypted_password: "abcdefghjklmnopqrstuvwxyz3"
  remember_created_at:
  created_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &3 2015-08-23 23:29:39.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *3
  updated_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &4 2016-03-31 15:09:34.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *4
  reset_password_token: abcdefghijklmnopqrstuvwxyz3
  reset_password_sent_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &5 2016-03-16 19:42:53.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *5
  two_factor_token: lgxobqrvbxp4p6tm
  roles: reviewer

two_factor_full:
  email: two_factor_full@user.com
  encrypted_password: "abcdefghjklmnopqrstuvwxyz3"
  remember_created_at:
  created_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &3 2015-08-23 23:29:39.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *3
  updated_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &4 2016-03-31 15:09:34.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *4
  reset_password_token: abcdefghijklmnopqrstuvwxyz3
  reset_password_sent_at: !ruby/object:ActiveSupport::TimeWithZone
    utc: &5 2016-03-16 19:42:53.000000000 Z
    zone: !ruby/object:ActiveSupport::TimeZone
      name: Etc/UTC
    time: *5
  two_factor_token: 7vqntzjy54hx2tkv
  enabled_2fa: true
  roles: reviewer