* User decorator (and spec) should use `trusted?`
Fixes a few issues seen in an rspec run that show as:
DEPRECATION WARNING: User#trusted is deprecated, favor
User#trusted? (called from config_body_class at
/opt/apps/forem/app/decorators/user_decorator.rb:58)
And here:
/opt/apps/forem/spec/decorators/user_decorator_spec.rb:112
/opt/apps/forem/spec/decorators/user_decorator_spec.rb:121
/opt/apps/forem/spec/decorators/user_decorator_spec.rb:130
/opt/apps/forem/spec/decorators/user_decorator_spec.rb:139
* prefer User trusted? to trusted
DEPRECATION WARNING: User#trusted is deprecated, favor
User#trusted? (called from permissions at
/opt/apps/forem/app/models/rating_vote.rb:25)
* Prefer trusted? to trusted in user spec
* Use warned? rather than warned in admin article partial
* use trusted? rather than trusted in moderator requests spec
* Prefer trusted? to trusted in moderations controller
* Prefer trusted? to trusted in moderations view
* User auditable? should call trusted? and not trusted
Deprecations go rolling right along.
* Invert guard clause logic to be positive
The original "return unless multiple negated conditions hold" guard
was cumbersome.
Invert to return if any of the exceptions apply, namely:
- this is a comment or readinglist rating (rather than explicit),
allowed for all
- this rating is from a moderator/trusted user (allowed)
- this rating is offered by the article's author (allowed)
I had intended to also remove the safe navigation operators (since it
wasn't clear why there would be a null user or null article, as
rating_vote joins users to articles with a score), but the builtin
validation tests (is expected to validate ...) build objects with
missing attributes, and raise errors when the spec is run.
161 lines
6.4 KiB
Text
161 lines
6.4 KiB
Text
<style>
|
|
.article-body-html img {
|
|
max-width: 100%;
|
|
}
|
|
</style>
|
|
|
|
<% decorated_article = article.decorate %>
|
|
|
|
<div class="card my-3"
|
|
data-controller="article"
|
|
data-article-id-value="<%= article.id %>"
|
|
data-article-pin-path-value="<%= stories_feed_pinned_article_path %>"
|
|
data-article-bg-highlighted-class="bg-highlighted"
|
|
data-article-border-highlighted-class="border-highlighted"
|
|
data-action="ajax:success@document->article#ajaxSuccess">
|
|
|
|
<div class="card-header">
|
|
<h2>
|
|
<a href="<%= article.path %>" target="_blank" rel="noopener">
|
|
<%= article.title %>
|
|
</a>
|
|
</h2>
|
|
|
|
<div>
|
|
<a href="<%= article.path %>/edit" target="_blank" rel="noopener"><span class="btn btn-sm btn-primary">Edit</span></a>
|
|
|
|
<a class="btn btn-sm btn-secondary" href="<%= admin_user_path(article.user_id) %>" target="_blank" rel="noopener">Manage User</a>
|
|
|
|
<% if decorated_article.pinned? %>
|
|
<%= link_to(
|
|
"Unpin Post",
|
|
unpin_admin_article_path(decorated_article.id),
|
|
method: :delete,
|
|
remote: true,
|
|
class: "btn btn-sm btn-secondary",
|
|
data: { "article-target": "unpinButton" },
|
|
) %>
|
|
<% else %>
|
|
<form method="post" action="<%= pin_admin_article_path(decorated_article.id) %>" class="inline"
|
|
data-action="submit->article#pinArticle">
|
|
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
|
|
<button type="submit" class="btn btn-sm btn-secondary">
|
|
Pin Post
|
|
</button>
|
|
</form>
|
|
<% end %>
|
|
|
|
<a href="<%= admin_user_path(article.user_id) %>" class="badge badge-light">@<%= article.user&.username %></a>
|
|
|
|
<span class="badge badge-light">❤️ <%= article.public_reactions_count %> 💬 <%= article.comments_count %></span>
|
|
|
|
<span class="badge badge-light">
|
|
<% if article.published_from_feed? && !article.published? %>
|
|
RSS Import <%= article.created_at.strftime("%b %d, %Y") %>
|
|
Originally Published <%= article.published_at&.strftime("%b %d, %Y") %>
|
|
<% elsif article.crossposted_at? %>
|
|
Crossposted <%= article.crossposted_at.strftime("%b %d, %Y") %> & Published
|
|
<%= article.published_at&.strftime("%b %d, %Y") %>
|
|
<% else %>
|
|
<%= article.published_at&.strftime("%b %d, %Y") %>
|
|
<% end %>
|
|
</span>
|
|
|
|
<% decorated_article.cached_tag_list_array.each do |tag| %>
|
|
<a class="badge badge-secondary" href='<%= tag_path(tag) %>'>#<%= tag %></a>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<% featured = article.featured ? "bg-featured" : "" %>
|
|
<% approved = article.approved ? "bg-approved" : featured %>
|
|
<% pinned = decorated_article.pinned? ? "bg-pinned" : approved %>
|
|
<% background_color = pinned %>
|
|
|
|
<div
|
|
data-article-target="cardBody"
|
|
class="card-body <%= background_color %> <%= "bg-danger" if !article.published? && article.published_from_feed? %>">
|
|
|
|
<% if article.video %>
|
|
<h2>Contains Video</h2>
|
|
<% end %>
|
|
|
|
<% cache "admin-user-info-#{article.user_id}-#{article.user&.updated_at}", expires_in: 4.hours do %>
|
|
|
|
<% if article.user&.warned? %>
|
|
<h2><span class="badge badge-warning">USER WARNED</span></h2>
|
|
<% end %>
|
|
|
|
<% if article.user&.notes&.any? %>
|
|
<h2>User Notes (<%= article.user&.notes&.size %> total)</h2>
|
|
<% article.user&.notes&.last(3)&.each do |note| %>
|
|
<p>
|
|
<em><%= note.created_at.strftime("%d %B %Y %H:%M UTC") %> by
|
|
<%= note.author_id ? User.find(note.author_id).username : "No Author" %></em> - <%= note.content %>
|
|
</p>
|
|
<% end %>
|
|
<p><a href="<%= admin_user_path(article.user_id) %>">View All</a></p>
|
|
<% end %>
|
|
<% end %>
|
|
<% if article.main_image.present? %>
|
|
<div style="max-height:450px;overflow:hidden;">
|
|
<img src="<%= cloud_cover_url(article.main_image) %>" style="width:100%;max-width:380px;border-radius:8px;background:<%= article.main_image_background_hex_color %>;" alt="cover image" loading="lazy" />
|
|
<br />
|
|
</div>
|
|
<% end %>
|
|
<%= form_with url: admin_article_path(article.id), model: article, local: true do |f| %>
|
|
<div class="form-group">
|
|
<input name="utf8" type="hidden" value="✓">
|
|
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
|
|
<input type="hidden" name="_method" value="patch" />
|
|
</div>
|
|
<div class="row">
|
|
<div class="form-group col">
|
|
<label for="featured_number_<%= article.id %>">Featured Number:</label>
|
|
<input id="featured_number_<%= article.id %>"
|
|
class="form-control"
|
|
name="article[featured_number]"
|
|
value="<%= article.featured_number %>"
|
|
data-article-target="featuredNumber">
|
|
</div>
|
|
<div class="form-group col">
|
|
<label for="author_id_<%= article.id %>">Author ID:</label>
|
|
<input id="author_id_<%= article.id %>" class="form-control" size="6" name="article[user_id]"
|
|
value="<%= article.user_id %>">
|
|
</div>
|
|
<div class="form-group col">
|
|
<label for="co_author_ids_list_<%= article.id %>">Co-Author IDs (comma separated):</label>
|
|
<input id="co_author_ids_list_<%= article.id %>" class="form-control" size="6" name="article[co_author_ids_list]"
|
|
value="<%= article.co_author_ids&.join(", ") %>">
|
|
</div>
|
|
</div>
|
|
<% if article.published? %>
|
|
<div class="row">
|
|
<div class="form-group col">
|
|
<label for="published_at_<%= article.id %>">Published at:</label>
|
|
<%= f.datetime_select :published_at, required: true, include_blank: true, include_seconds: true, class: "form-control" %> UTC
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
<div class="row">
|
|
<div class="form-check col">
|
|
<%= f.check_box :featured, id: "featured-#{article.id}" %>
|
|
<label for="featured-<%= article.id %>">Featured</label>
|
|
</div>
|
|
<div class="form-check col">
|
|
<%= f.check_box :approved, id: "approved-#{article.id}" %>
|
|
<label for="approved-<%= article.id %>">Approved</label>
|
|
</div>
|
|
<div class="form-check col">
|
|
<div class="form-check col">
|
|
<% if decorated_article.pinned? %>
|
|
<span class="badge badge-success">Pinned Post</span>
|
|
<% end %>
|
|
</div>
|
|
<div class="col">
|
|
<button class="btn btn-primary float-right">Submit</button>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|