Add dashboard to admin page
This commit is contained in:
parent
3d6ae08e84
commit
484e70a68f
17 changed files with 454 additions and 168 deletions
75
app/assets/javascripts/app/pages/admin_dashboard.js
Normal file
75
app/assets/javascripts/app/pages/admin_dashboard.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
||||
|
||||
app.pages.AdminDashboard = Backbone.View.extend({
|
||||
initialize: function() {
|
||||
this.updatePodStatus();
|
||||
},
|
||||
|
||||
updatePodStatus: function() {
|
||||
var self = this,
|
||||
tagName = "";
|
||||
$.get("https://api.github.com/repos/diaspora/diaspora/releases/latest")
|
||||
.done(function(data) {
|
||||
// the response might be malformed
|
||||
try {
|
||||
/* jshint camelcase: false */
|
||||
tagName = data.tag_name;
|
||||
/* jshint camelcase: true */
|
||||
if(tagName.charAt(0) !== "v") {
|
||||
self.updatePodStatusFail();
|
||||
return;
|
||||
}
|
||||
} catch(e) {
|
||||
self.updatePodStatusFail();
|
||||
return;
|
||||
}
|
||||
|
||||
// split version into components
|
||||
self.latestVersion = tagName.slice(1).split(".").map(Number);
|
||||
if(self.podUpToDate() === null) {
|
||||
self.updatePodStatusFail();
|
||||
} else {
|
||||
self.updatePodStatusSuccess();
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
self.updatePodStatusFail();
|
||||
});
|
||||
},
|
||||
|
||||
updatePodStatusSuccess: function() {
|
||||
$("#pod-status .alert").removeClass("alert-info");
|
||||
var podStatusMessage = Diaspora.I18n.t("admins.dashboard.up_to_date");
|
||||
if(this.podUpToDate()) {
|
||||
$("#pod-status .alert").addClass("alert-success");
|
||||
} else {
|
||||
podStatusMessage = Diaspora.I18n.t("admins.dashboard.outdated");
|
||||
$("#pod-status .alert").addClass("alert-danger");
|
||||
}
|
||||
$("#pod-status .alert")
|
||||
.html("<strong>" + podStatusMessage + "</strong>")
|
||||
.append(" ")
|
||||
.append(Diaspora.I18n.t("admins.dashboard.compare_versions", {
|
||||
latestVersion: "v" + this.latestVersion.join("."),
|
||||
podVersion: "v" + gon.podVersion
|
||||
}));
|
||||
},
|
||||
|
||||
updatePodStatusFail: function() {
|
||||
$("#pod-status .alert")
|
||||
.removeClass("alert-info")
|
||||
.addClass("alert-warning")
|
||||
.text(Diaspora.I18n.t("admins.dashboard.error"));
|
||||
},
|
||||
|
||||
podUpToDate: function() {
|
||||
var podVersion = gon.podVersion.split(/\.|\-/).map(Number);
|
||||
if(this.latestVersion.length < 4 || podVersion.length < 4) { return null; }
|
||||
for(var i = 0; i < 4; i++) {
|
||||
if(this.latestVersion[i] < podVersion[i]) { return true; }
|
||||
if(this.latestVersion[i] > podVersion[i]) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
// @license-end
|
||||
|
|
@ -10,6 +10,7 @@ app.Router = Backbone.Router.extend({
|
|||
"user/edit": "settings",
|
||||
"users/sign_up": "registration",
|
||||
"profile/edit": "settings",
|
||||
"admins/dashboard": "adminDashboard",
|
||||
|
||||
//new hotness
|
||||
"posts/:id": "singlePost",
|
||||
|
|
@ -47,6 +48,10 @@ app.Router = Backbone.Router.extend({
|
|||
app.help.render(section);
|
||||
},
|
||||
|
||||
adminDashboard: function() {
|
||||
app.page = new app.pages.AdminDashboard();
|
||||
},
|
||||
|
||||
contacts: function() {
|
||||
app.aspect = new app.models.Aspect(gon.preloads.aspect);
|
||||
app.contacts = new app.collections.Contacts(app.parsePreload("contacts"));
|
||||
|
|
|
|||
|
|
@ -1,30 +1,6 @@
|
|||
@import 'colors';
|
||||
|
||||
/** ADMIN STYlES **/
|
||||
|
||||
body > div.container {
|
||||
margin-top: 40px;
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
#admin_nav {
|
||||
font-size: 1em;
|
||||
border-bottom: 2px solid #777;
|
||||
margin-bottom: 20px;
|
||||
|
||||
ul {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 0.8em;
|
||||
display: inline;
|
||||
margin-right: 0.5em;
|
||||
|
||||
a { color: $blue; }
|
||||
}
|
||||
}
|
||||
|
||||
/** user search **/
|
||||
|
||||
.users {
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@
|
|||
<li><a href="/user/edit">{{t "header.settings"}}</a></li>
|
||||
<li><a href="/help">{{t "header.help"}}</a></li>
|
||||
{{#if current_user.admin}}
|
||||
<li><a href="/admins/user_search">{{t "header.admin"}}</a></li>
|
||||
<li><a href="/admins/dashboard">{{t "header.admin"}}</a></li>
|
||||
{{/if}}
|
||||
<li><a href="/users/sign_out" data-method="delete">{{t "header.log_out"}}</a></li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
class AdminsController < Admin::AdminController
|
||||
include ApplicationHelper
|
||||
|
||||
def dashboard
|
||||
gon.push(pod_version: pod_version)
|
||||
end
|
||||
|
||||
def user_search
|
||||
if params[:admins_controller_user_search]
|
||||
|
|
|
|||
|
|
@ -1,15 +1,21 @@
|
|||
|
||||
- content_for :head do
|
||||
= stylesheet_link_tag :admin
|
||||
|
||||
#admin_nav
|
||||
%h2
|
||||
= t('.pages')
|
||||
%ul
|
||||
%li= link_to t('.user_search'), user_search_path
|
||||
%li= link_to t('.weekly_user_stats'), weekly_user_stats_path
|
||||
%li= link_to t('.pod_stats'), pod_stats_path
|
||||
%li= link_to t('.report'), report_index_path
|
||||
%li= link_to t('.correlations'), correlations_path
|
||||
%li= link_to t('.sidekiq_monitor'), sidekiq_path
|
||||
%h2= t(".pages")
|
||||
|
||||
%ul#admin_nav.nav.nav-pills.nav-stacked
|
||||
%li{role: "presentation", class: current_page?(admin_dashboard_path) && "active"}
|
||||
= link_to t('.dashboard'), admin_dashboard_path
|
||||
%li{role: "presentation", class: current_page?(user_search_path) && "active"}
|
||||
= link_to t('.user_search'), user_search_path
|
||||
%li{role: "presentation", class: current_page?(weekly_user_stats_path) && "active"}
|
||||
= link_to t('.weekly_user_stats'), weekly_user_stats_path
|
||||
%li{role: "presentation", class: current_page?(pod_stats_path) && "active"}
|
||||
= link_to t('.pod_stats'), pod_stats_path
|
||||
%li{role: "presentation", class: current_page?(report_index_path) && "active"}
|
||||
= link_to t('.report'), report_index_path
|
||||
%li{role: "presentation", class: current_page?(correlations_path) && "active"}
|
||||
= link_to t('.correlations'), correlations_path
|
||||
%li{role: "presentation", class: current_page?(sidekiq_path) && "active"}
|
||||
= link_to t('.sidekiq_monitor'), sidekiq_path
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
.container
|
||||
%div
|
||||
= render :partial => 'admins/admin_bar'
|
||||
|
||||
%div.row
|
||||
%div.col-md-12
|
||||
.row
|
||||
.col-md-3
|
||||
= render partial: "admins/admin_bar"
|
||||
.col-md-9
|
||||
%h1
|
||||
= t('.correlations_count')
|
||||
%ul
|
||||
|
|
|
|||
10
app/views/admins/dashboard.html.haml
Normal file
10
app/views/admins/dashboard.html.haml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
.container
|
||||
.row
|
||||
.col-md-3
|
||||
= render partial: "admins/admin_bar"
|
||||
.col-md-9
|
||||
#pod-status
|
||||
%h2
|
||||
= t(".pod_status")
|
||||
.alert.alert-info{role: "alert"}
|
||||
= t(".fetching_diaspora_version")
|
||||
|
|
@ -1,56 +1,56 @@
|
|||
.container
|
||||
%div
|
||||
= render :partial => 'admins/admin_bar'
|
||||
.row
|
||||
.col-md-3
|
||||
= render partial: "admins/admin_bar"
|
||||
.col-md-9
|
||||
%h1= t('.usage_statistic')
|
||||
|
||||
%h1
|
||||
= t('.usage_statistic')
|
||||
.pull-right
|
||||
= form_tag('/admins/stats', :method => 'get', class: 'form-inline') do
|
||||
%select{:name => 'range'}
|
||||
%option{:value => 'daily', :selected => ('selected' if params[:range] == 'daily')}
|
||||
= t('.daily')
|
||||
%option{:value => 'week', :selected => ('selected' if params[:range] == 'week')}
|
||||
= t('.week')
|
||||
%option{:value => '2weeks', :selected => ('selected' if params[:range] == '2weeks')}
|
||||
= t('.2weeks')
|
||||
%option{:value => 'month', :selected => ('selected' if params[:range] == 'month')}
|
||||
= t('.month')
|
||||
|
||||
%div.pull-right
|
||||
= form_tag('/admins/stats', :method => 'get', class: 'form-inline') do
|
||||
%select{:name => 'range'}
|
||||
%option{:value => 'daily', :selected => ('selected' if params[:range] == 'daily')}
|
||||
= t('.daily')
|
||||
%option{:value => 'week', :selected => ('selected' if params[:range] == 'week')}
|
||||
= t('.week')
|
||||
%option{:value => '2weeks', :selected => ('selected' if params[:range] == '2weeks')}
|
||||
= t('.2weeks')
|
||||
%option{:value => 'month', :selected => ('selected' if params[:range] == 'month')}
|
||||
= t('.month')
|
||||
= submit_tag t('.go'), class: 'btn btn-primary'
|
||||
|
||||
= submit_tag t('.go'), class: 'btn btn-primary'
|
||||
%h3
|
||||
!= t('.display_results', :segment => @segment)
|
||||
|
||||
%h3
|
||||
!= t('.display_results', :segment => @segment)
|
||||
.row
|
||||
- [:posts, :comments, :aspect_memberships, :users].each do |name|
|
||||
- model = eval("@#{name.to_s}")
|
||||
- if name == :aspect_memberships
|
||||
- name = t('.shares', :count => model[:yesterday])
|
||||
- if name == :posts
|
||||
- name = t('.posts', :count => model[:yesterday])
|
||||
- if name == :comments
|
||||
- name = t('.comments', :count => model[:yesterday])
|
||||
- if name == :users
|
||||
- name = t('.users', :count => model[:yesterday])
|
||||
|
||||
%div.row
|
||||
- [:posts, :comments, :aspect_memberships, :users].each do |name|
|
||||
- model = eval("@#{name.to_s}")
|
||||
- if name == :aspect_memberships
|
||||
- name = t('.shares', :count => model[:yesterday])
|
||||
- if name == :posts
|
||||
- name = t('.posts', :count => model[:yesterday])
|
||||
- if name == :comments
|
||||
- name = t('.comments', :count => model[:yesterday])
|
||||
- if name == :users
|
||||
- name = t('.users', :count => model[:yesterday])
|
||||
.col-md-3
|
||||
%h2{:style => 'font-weight:bold;'}
|
||||
= name.to_s
|
||||
%h4
|
||||
= model[:day_before]
|
||||
%span.percent_change{:class => (model[:change] > 0 ? "green" : "red")}
|
||||
= "(#{model[:change]}%)"
|
||||
|
||||
.col-md-3
|
||||
%h2{:style => 'font-weight:bold;'}
|
||||
= name.to_s
|
||||
%h4
|
||||
= model[:day_before]
|
||||
%span.percent_change{:class => (model[:change] > 0 ? "green" : "red")}
|
||||
= "(#{model[:change]}%)"
|
||||
.row
|
||||
.col-md-12
|
||||
%p.alert.alert-info.text-center
|
||||
!= t('.current_segment', :post_yest => @posts[:yesterday]/@user_count.to_f, :post_day => @posts[:day_before]/@user_count.to_f)
|
||||
|
||||
%div.row
|
||||
%div.col-md-12
|
||||
%p.alert.alert-info.text-center
|
||||
!= t('.current_segment', :post_yest => @posts[:yesterday]/@user_count.to_f, :post_day => @posts[:day_before]/@user_count.to_f)
|
||||
|
||||
%div.row
|
||||
%div.col-md-12
|
||||
%h3= t('.50_most')
|
||||
%ul
|
||||
- @popular_tags.each do |name,count|
|
||||
%li
|
||||
!= t('.tag_name', :name_tag => name, :count_tag => count)
|
||||
.row
|
||||
.col-md-12
|
||||
%h3= t('.50_most')
|
||||
%ul
|
||||
- @popular_tags.each do |name,count|
|
||||
%li
|
||||
!= t('.tag_name', :name_tag => name, :count_tag => count)
|
||||
|
|
|
|||
|
|
@ -1,58 +1,59 @@
|
|||
.container
|
||||
%div
|
||||
= render :partial => 'admins/admin_bar'
|
||||
.row
|
||||
.col-md-3
|
||||
= render partial: "admins/admin_bar"
|
||||
.col-md-9
|
||||
.row
|
||||
.user_search.col-md-8
|
||||
%h3= t('admins.admin_bar.user_search')
|
||||
= form_for @search, url: {action: 'user_search'}, html: {method: :get, class: 'form-horizontal'} do |f|
|
||||
.form-group
|
||||
= f.label :username, t('username'), class: 'col-sm-2 control-label'
|
||||
.col-sm-10
|
||||
= f.text_field :username, class: "form-control"
|
||||
|
||||
%div.row
|
||||
%div.user_search.col-md-8
|
||||
%h3= t('admins.admin_bar.user_search')
|
||||
= form_for @search, url: {action: 'user_search'}, html: {method: :get, class: 'form-horizontal'} do |f|
|
||||
%div.form-group
|
||||
= f.label :username, t('username'), class: 'col-sm-2 control-label'
|
||||
%div.col-sm-10
|
||||
= f.text_field :username, class: "form-control"
|
||||
.form-group
|
||||
= f.label :email, t('email'), class: 'col-sm-2 control-label'
|
||||
.col-sm-10
|
||||
= f.text_field :email, class: "form-control"
|
||||
|
||||
%div.form-group
|
||||
= f.label :email, t('email'), class: 'col-sm-2 control-label'
|
||||
%div.col-sm-10
|
||||
= f.text_field :email, class: "form-control"
|
||||
.form-group
|
||||
= f.label :guid, t('admins.user_entry.guid'), class: 'col-sm-2 control-label'
|
||||
.col-sm-10
|
||||
= f.text_field :guid, class: "form-control"
|
||||
|
||||
%div.form-group
|
||||
= f.label :guid, t('admins.user_entry.guid'), class: 'col-sm-2 control-label'
|
||||
%div.col-sm-10
|
||||
= f.text_field :guid, class: "form-control"
|
||||
.form-group
|
||||
.col-sm-offset-2.col-sm-10
|
||||
= f.label :under13 do
|
||||
= f.check_box :under13
|
||||
= t(".under_13")
|
||||
.form-group
|
||||
.clearfix.col-sm-12
|
||||
= submit_tag t("admins.stats.go"), class: "btn btn-primary pull-right"
|
||||
|
||||
%div.form-group
|
||||
%div.col-sm-offset-2.col-sm-10
|
||||
= f.label :under13 do
|
||||
= f.check_box :under13
|
||||
= t(".under_13")
|
||||
%div.form-group
|
||||
%div.clearfix.col-sm-12
|
||||
= submit_tag t("admins.stats.go"), class: "btn btn-primary pull-right"
|
||||
.more_invites.col-md-4
|
||||
%h3= t("shared.invitations.invites")
|
||||
#add-invites-section.clearfix
|
||||
!= t(".you_currently", count: current_user.invitation_code.count,
|
||||
link: link_to(t(".add_invites"), add_invites_path(current_user.invitation_code),
|
||||
class: "btn btn-link pull-right"))
|
||||
|
||||
%div.more_invites.col-md-4
|
||||
%h3= t("shared.invitations.invites")
|
||||
#add-invites-section.clearfix
|
||||
!= t(".you_currently", count: current_user.invitation_code.count,
|
||||
link: link_to(t(".add_invites"), add_invites_path(current_user.invitation_code),
|
||||
class: "btn btn-link pull-right"))
|
||||
= form_tag "admin_inviter", method: :get, class: "form-horizontal" do
|
||||
.form-group
|
||||
%label.col-sm-4.control-label
|
||||
= t(".email_to")
|
||||
.col-sm-8
|
||||
= text_field_tag "identifier", nil, class: "form-control"
|
||||
.form-group
|
||||
.clearfix.col-md-12
|
||||
= submit_tag t("services.remote_friend.invite"), class: "btn btn-default pull-right"
|
||||
|
||||
= form_tag "admin_inviter", method: :get, class: "form-horizontal" do
|
||||
.form-group
|
||||
%label.col-sm-4.control-label
|
||||
= t(".email_to")
|
||||
.col-sm-8
|
||||
= text_field_tag "identifier", nil, class: "form-control"
|
||||
.form-group
|
||||
.clearfix.col-md-12
|
||||
= submit_tag t("services.remote_friend.invite"), class: "btn btn-default pull-right"
|
||||
.row
|
||||
.col-md-12
|
||||
.alert.alert-info.text-center= t('.users', :count => @users.count)
|
||||
|
||||
%div.row
|
||||
%div.col-md-12
|
||||
%div.alert.alert-info.text-center= t('.users', :count => @users.count)
|
||||
|
||||
%div.row
|
||||
%div.users.col-md-12
|
||||
%ul.media-list
|
||||
- @users.each do |user|
|
||||
= render partial: 'user_entry', locals: { user: user }
|
||||
.row
|
||||
.users.col-md-12
|
||||
%ul.media-list
|
||||
- @users.each do |user|
|
||||
= render partial: 'user_entry', locals: { user: user }
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
.container
|
||||
%div
|
||||
= render :partial => 'admins/admin_bar'
|
||||
.row
|
||||
.col-md-3
|
||||
= render partial: "admins/admin_bar"
|
||||
.col-md-9
|
||||
%h2
|
||||
= t('.current_server', date: Time.now.to_date)
|
||||
|
||||
%h2
|
||||
= t('.current_server', date: Time.now.to_date)
|
||||
.pull-right
|
||||
= form_tag('/admins/weekly_user_stats', method: 'get', class: 'form-inline') do
|
||||
= select_tag(:week, options_for_select(@created_users_by_week.keys.reverse, @selected_week))
|
||||
= submit_tag t('admins.stats.go'), class: 'btn btn-primary'
|
||||
|
||||
%div.pull-right
|
||||
= form_tag('/admins/weekly_user_stats', method: 'get', class: 'form-inline') do
|
||||
= select_tag(:week, options_for_select(@created_users_by_week.keys.reverse, @selected_week))
|
||||
= submit_tag t('admins.stats.go'), class: 'btn btn-primary'
|
||||
|
||||
= t('.amount_of', count: @counter)
|
||||
%br
|
||||
- @created_users_by_week[@selected_week].each do |m|
|
||||
= link_to m, "/u/#{m}"
|
||||
%br
|
||||
= t('.amount_of', count: @counter)
|
||||
%br
|
||||
- @created_users_by_week[@selected_week].each do |m|
|
||||
= link_to m, "/u/#{m}"
|
||||
%br
|
||||
|
|
|
|||
|
|
@ -1,22 +1,21 @@
|
|||
.container
|
||||
%div
|
||||
= render :partial => 'admins/admin_bar'
|
||||
|
||||
%div.row
|
||||
%div.col-md-12
|
||||
.row
|
||||
.col-md-3
|
||||
= render partial: "admins/admin_bar"
|
||||
.col-md-9
|
||||
%h1
|
||||
= t('report.title')
|
||||
%div#reports
|
||||
#reports
|
||||
- @reports.each do |r|
|
||||
- username = User.find_by_id(r.user_id).username
|
||||
%div.content
|
||||
.content
|
||||
%span.text
|
||||
= report_content(r.item_id, r.item_type)
|
||||
%span
|
||||
= raw t('report.reported_label', person: link_to(username, user_profile_path(username)))
|
||||
%span
|
||||
= t('report.reason_label', text: r.text)
|
||||
%div.options.text-right
|
||||
.options.text-right
|
||||
%span
|
||||
= button_to t('report.review_link'), report_path(r.id, :type => r.item_type),
|
||||
:class => "btn btn-info btn-small",
|
||||
|
|
@ -26,4 +25,4 @@
|
|||
:data => { :confirm => t('report.confirm_deletion') },
|
||||
:class => "btn btn-danger btn-small",
|
||||
method: :delete
|
||||
%div.clear
|
||||
.clear
|
||||
|
|
|
|||
|
|
@ -98,12 +98,16 @@ en:
|
|||
admins:
|
||||
admin_bar:
|
||||
pages: "Pages"
|
||||
dashboard: "Dashboard"
|
||||
user_search: "User search"
|
||||
weekly_user_stats: "Weekly user stats"
|
||||
pod_stats: "Pod stats"
|
||||
report: "Reports"
|
||||
correlations: "Correlations"
|
||||
sidekiq_monitor: "Sidekiq monitor"
|
||||
dashboard:
|
||||
pod_status: "Pod status"
|
||||
fetching_diaspora_version: "Fetching current diaspora* version..."
|
||||
correlations:
|
||||
correlations_count: "Correlations with sign-in count:"
|
||||
user_search:
|
||||
|
|
|
|||
|
|
@ -29,6 +29,13 @@ en:
|
|||
edit: "Edit"
|
||||
no_results: "No results found"
|
||||
|
||||
admins:
|
||||
dashboard:
|
||||
up_to_date: "Your pod is up to date!"
|
||||
outdated: "Your pod is outdated."
|
||||
compare_versions: "The latest diaspora* release is <%= latestVersion %>, your pod is running <%= podVersion %>."
|
||||
error: "Error fetching the latest diaspora* version."
|
||||
|
||||
aspects:
|
||||
make_aspect_list_visible: "Make contacts in this aspect visible to each other?"
|
||||
name: "Name"
|
||||
|
|
|
|||
|
|
@ -141,13 +141,14 @@ Diaspora::Application.routes.draw do
|
|||
|
||||
# Admin backend routes
|
||||
|
||||
scope 'admins', :controller => :admins do
|
||||
scope "admins", controller: :admins do
|
||||
match :user_search, via: [:get, :post]
|
||||
get :admin_inviter
|
||||
get :weekly_user_stats
|
||||
get :correlations
|
||||
get :stats, :as => 'pod_stats'
|
||||
get "add_invites/:invite_code_id" => 'admins#add_invites', :as => 'add_invites'
|
||||
get :admin_inviter
|
||||
get :weekly_user_stats
|
||||
get :correlations
|
||||
get :stats, as: "pod_stats"
|
||||
get :dashboard, as: "admin_dashboard"
|
||||
get "add_invites/:invite_code_id" => "admins#add_invites", :as => "add_invites"
|
||||
end
|
||||
|
||||
namespace :admin do
|
||||
|
|
|
|||
18
spec/controllers/jasmine_fixtures/admins_spec.rb
Normal file
18
spec/controllers/jasmine_fixtures/admins_spec.rb
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe AdminsController, type: :controller do
|
||||
describe "#dashboard" do
|
||||
before do
|
||||
@user = FactoryGirl.create :user
|
||||
Role.add_admin(@user.person)
|
||||
sign_in :user, @user
|
||||
end
|
||||
|
||||
context "jasmine fixtures" do
|
||||
it "generates a jasmine fixture", fixture: true do
|
||||
get :dashboard
|
||||
save_fixture(html_for("body"), "admin_dashboard")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
179
spec/javascripts/app/pages/admin_dashboard_spec.js
Normal file
179
spec/javascripts/app/pages/admin_dashboard_spec.js
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
describe("app.pages.AdminDashboard", function(){
|
||||
beforeEach(function() {
|
||||
spec.loadFixture("admin_dashboard");
|
||||
this.view = new app.pages.AdminDashboard();
|
||||
gon.podVersion = "0.5.1.2";
|
||||
// disable jshint camelcase for i18n
|
||||
/* jshint camelcase: false */
|
||||
Diaspora.I18n.load({
|
||||
admins: {
|
||||
dashboard: {
|
||||
up_to_date: "Your pod is up to date!",
|
||||
outdated: "Your pod is outdated.",
|
||||
compare_versions: "Latest d* release is <%= latestVersion%>, your pod is running <%= podVersion %>.",
|
||||
error: "Error fetching the latest diaspora* version."
|
||||
}
|
||||
}
|
||||
});
|
||||
/* jshint camelcase: true */
|
||||
});
|
||||
|
||||
describe("initialize" , function() {
|
||||
it("calls updatePodStatus", function() {
|
||||
spyOn(this.view, "updatePodStatus");
|
||||
this.view.initialize();
|
||||
expect(this.view.updatePodStatus).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("updatePodStatus" , function() {
|
||||
it("sends an ajax request to the github API", function() {
|
||||
this.view.updatePodStatus();
|
||||
expect(jasmine.Ajax.requests.mostRecent().url).toBe(
|
||||
"https://api.github.com/repos/diaspora/diaspora/releases/latest"
|
||||
);
|
||||
});
|
||||
|
||||
it("calls updatePodStatusFail on a failed request", function() {
|
||||
spyOn(this.view, "updatePodStatusFail");
|
||||
this.view.updatePodStatus();
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({status: 400});
|
||||
expect(this.view.updatePodStatusFail).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("calls updatePodStatusFail on a malformed response", function() {
|
||||
spyOn(this.view, "updatePodStatusFail");
|
||||
spyOn(this.view, "podUpToDate").and.returnValue(true);
|
||||
var responses = [
|
||||
// no object
|
||||
"text",
|
||||
// object without tag_name
|
||||
"{\"tag\": 0}",
|
||||
// tag_name not a string
|
||||
"{\"tag_name\": 0}",
|
||||
"{\"tag_name\": {\"id\": 0}}",
|
||||
// tag_name doesn't start with "v"
|
||||
"{\"tag_name\": \"0.5.1.2\"}"
|
||||
];
|
||||
|
||||
for(var i = 0; i < responses.length; i++) {
|
||||
this.view.updatePodStatus();
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 200,
|
||||
responseText: responses[i]
|
||||
});
|
||||
expect(this.view.updatePodStatusFail.calls.count()).toEqual(i+1);
|
||||
}
|
||||
});
|
||||
|
||||
it("sets latestVersion on a correct response", function() {
|
||||
this.view.updatePodStatus();
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 200,
|
||||
responseText: "{\"tag_name\": \"v0.5.1.2\"}"
|
||||
});
|
||||
expect(this.view.latestVersion).toEqual([0,5,1,2]);
|
||||
});
|
||||
|
||||
it("calls podUpToDate on a correct response", function() {
|
||||
spyOn(this.view, "podUpToDate");
|
||||
this.view.updatePodStatus();
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 200,
|
||||
responseText: "{\"tag_name\": \"v0.5.1.2\"}"
|
||||
});
|
||||
expect(this.view.podUpToDate).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("calls updatePodStatusFail if podUpToDate returns null", function() {
|
||||
spyOn(this.view, "updatePodStatusFail");
|
||||
spyOn(this.view, "podUpToDate").and.returnValue(null);
|
||||
this.view.updatePodStatus();
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 200,
|
||||
responseText: "{\"tag_name\": \"v0.5.1.2\"}"
|
||||
});
|
||||
expect(this.view.updatePodStatusFail).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("calls updatePodStatusSuccess if podUpToDate returns a Boolean", function() {
|
||||
spyOn(this.view, "updatePodStatusSuccess");
|
||||
spyOn(this.view, "podUpToDate").and.returnValue(false);
|
||||
this.view.updatePodStatus();
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 200,
|
||||
responseText: "{\"tag_name\": \"v0.5.1.2\"}"
|
||||
});
|
||||
expect(this.view.updatePodStatusSuccess).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("podUpToDate" , function() {
|
||||
it("returns null if latestVersion is not long enough", function() {
|
||||
this.view.latestVersion = [0, 5, 1];
|
||||
expect(this.view.podUpToDate()).toBeNull();
|
||||
});
|
||||
|
||||
it("returns true if the pod is up to date", function() {
|
||||
var self = this;
|
||||
[
|
||||
{latest: "0.5.1.2", pod: "0.5.1.2"},
|
||||
{latest: "0.5.1.2", pod: "0.5.1.2-abcdefg"},
|
||||
{latest: "0.5.1.2", pod: "0.5.1.2-2"},
|
||||
{latest: "0.5.1.2", pod: "0.5.1.3"},
|
||||
{latest: "0.5.1.2", pod: "0.5.2.1"},
|
||||
{latest: "0.5.1.2", pod: "0.6.0.0"},
|
||||
{latest: "0.5.1.2", pod: "2.0.0.0"}
|
||||
].forEach(function(version) {
|
||||
gon.podVersion = version.pod;
|
||||
self.view.latestVersion = version.latest.split(".").map(Number);
|
||||
expect(self.view.podUpToDate()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it("returns false if the pod is outdated", function() {
|
||||
var self = this;
|
||||
[
|
||||
{latest: "0.5.1.2", pod: "0.5.1.1"},
|
||||
{latest: "0.5.1.2", pod: "0.5.1.1-abcdefg"},
|
||||
{latest: "0.5.1.2", pod: "0.5.1.1-2"},
|
||||
{latest: "0.5.1.2", pod: "0.4.99.4"},
|
||||
{latest: "2.0.3.5", pod: "1.99.2.1"}
|
||||
].forEach(function(version) {
|
||||
gon.podVersion = version.pod;
|
||||
self.view.latestVersion = version.latest.split(".").map(Number);
|
||||
expect(self.view.podUpToDate()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("updatePodStatusSuccess", function() {
|
||||
it("adds a 'success' alert if the pod is up to date", function() {
|
||||
spyOn(this.view, "podUpToDate").and.returnValue(true);
|
||||
this.view.latestVersion = [0, 5, 1, 1];
|
||||
this.view.updatePodStatusSuccess();
|
||||
expect($("#pod-status .alert")).toHaveClass("alert-success");
|
||||
expect($("#pod-status .alert").text()).toContain("up to date");
|
||||
expect($("#pod-status .alert").text()).toContain("release is v0.5.1.1");
|
||||
expect($("#pod-status .alert").text()).toContain("pod is running v0.5.1.2");
|
||||
});
|
||||
|
||||
it("adds a 'danger' alert if the pod is up to date", function() {
|
||||
spyOn(this.view, "podUpToDate").and.returnValue(false);
|
||||
this.view.latestVersion = [0, 5, 1, 3];
|
||||
this.view.updatePodStatusSuccess();
|
||||
expect($("#pod-status .alert")).toHaveClass("alert-danger");
|
||||
expect($("#pod-status .alert").text()).toContain("outdated");
|
||||
expect($("#pod-status .alert").text()).toContain("release is v0.5.1.3");
|
||||
expect($("#pod-status .alert").text()).toContain("pod is running v0.5.1.2");
|
||||
});
|
||||
});
|
||||
|
||||
describe("updatePodStatusFail", function() {
|
||||
it("adds a 'warning' alert", function() {
|
||||
this.view.updatePodStatusFail();
|
||||
expect($("#pod-status .alert")).toHaveClass("alert-warning");
|
||||
expect($("#pod-status .alert").text()).toContain("Error");
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue