diff --git a/app/assets/javascripts/app/pages/admin_dashboard.js b/app/assets/javascripts/app/pages/admin_dashboard.js
new file mode 100644
index 000000000..4826c12ea
--- /dev/null
+++ b/app/assets/javascripts/app/pages/admin_dashboard.js
@@ -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("" + podStatusMessage + "")
+ .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
diff --git a/app/assets/javascripts/app/router.js b/app/assets/javascripts/app/router.js
index db7acc146..6ec0618fd 100644
--- a/app/assets/javascripts/app/router.js
+++ b/app/assets/javascripts/app/router.js
@@ -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"));
diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss
index f8caef389..76006defc 100644
--- a/app/assets/stylesheets/admin.scss
+++ b/app/assets/stylesheets/admin.scss
@@ -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 {
diff --git a/app/assets/templates/header_tpl.jst.hbs b/app/assets/templates/header_tpl.jst.hbs
index 6c1da3182..044fc4af8 100644
--- a/app/assets/templates/header_tpl.jst.hbs
+++ b/app/assets/templates/header_tpl.jst.hbs
@@ -92,7 +92,7 @@
{{t "header.settings"}}
{{t "header.help"}}
{{#if current_user.admin}}
- {{t "header.admin"}}
+ {{t "header.admin"}}
{{/if}}
{{t "header.log_out"}}
diff --git a/app/controllers/admins_controller.rb b/app/controllers/admins_controller.rb
index cf85c0184..f90860ad8 100644
--- a/app/controllers/admins_controller.rb
+++ b/app/controllers/admins_controller.rb
@@ -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]
diff --git a/app/views/admins/_admin_bar.haml b/app/views/admins/_admin_bar.haml
index 75145d1be..9434736ec 100644
--- a/app/views/admins/_admin_bar.haml
+++ b/app/views/admins/_admin_bar.haml
@@ -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
diff --git a/app/views/admins/correlations.haml b/app/views/admins/correlations.haml
index b83fd6759..c2d8d391f 100644
--- a/app/views/admins/correlations.haml
+++ b/app/views/admins/correlations.haml
@@ -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
diff --git a/app/views/admins/dashboard.html.haml b/app/views/admins/dashboard.html.haml
new file mode 100644
index 000000000..bf7fd1089
--- /dev/null
+++ b/app/views/admins/dashboard.html.haml
@@ -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")
diff --git a/app/views/admins/stats.html.haml b/app/views/admins/stats.html.haml
index f14123d57..0dc6fac66 100644
--- a/app/views/admins/stats.html.haml
+++ b/app/views/admins/stats.html.haml
@@ -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)
diff --git a/app/views/admins/user_search.html.haml b/app/views/admins/user_search.html.haml
index 741eba693..91a516ceb 100644
--- a/app/views/admins/user_search.html.haml
+++ b/app/views/admins/user_search.html.haml
@@ -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 }
diff --git a/app/views/admins/weekly_user_stats.haml b/app/views/admins/weekly_user_stats.haml
index 901933a97..fbda59583 100644
--- a/app/views/admins/weekly_user_stats.haml
+++ b/app/views/admins/weekly_user_stats.haml
@@ -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
diff --git a/app/views/report/index.html.haml b/app/views/report/index.html.haml
index 46ee43c0b..0b8563729 100644
--- a/app/views/report/index.html.haml
+++ b/app/views/report/index.html.haml
@@ -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
diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml
index 4c12ce8c9..b21f6d21c 100644
--- a/config/locales/diaspora/en.yml
+++ b/config/locales/diaspora/en.yml
@@ -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:
diff --git a/config/locales/javascript/javascript.en.yml b/config/locales/javascript/javascript.en.yml
index f6755516f..b6a682692 100644
--- a/config/locales/javascript/javascript.en.yml
+++ b/config/locales/javascript/javascript.en.yml
@@ -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"
diff --git a/config/routes.rb b/config/routes.rb
index c0fd79d2b..01bfae30a 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -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
diff --git a/spec/controllers/jasmine_fixtures/admins_spec.rb b/spec/controllers/jasmine_fixtures/admins_spec.rb
new file mode 100644
index 000000000..73086e9a3
--- /dev/null
+++ b/spec/controllers/jasmine_fixtures/admins_spec.rb
@@ -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
diff --git a/spec/javascripts/app/pages/admin_dashboard_spec.js b/spec/javascripts/app/pages/admin_dashboard_spec.js
new file mode 100644
index 000000000..29ba0b733
--- /dev/null
+++ b/spec/javascripts/app/pages/admin_dashboard_spec.js
@@ -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");
+ });
+ });
+});