diff --git a/admin/.gitignore b/admin/.gitignore
index d747d53e8..fae983383 100644
--- a/admin/.gitignore
+++ b/admin/.gitignore
@@ -22,3 +22,4 @@ artifacts
BUILD_NUMBER
# Gemfile.lock
Gemfile.alt.lock
+.byebug_history
diff --git a/ruby/.gitignore b/ruby/.gitignore
index 048a017ca..fe1f4d2c5 100644
--- a/ruby/.gitignore
+++ b/ruby/.gitignore
@@ -22,3 +22,4 @@ vendor
*~
*.swp
*.iml
+.byebug_history
diff --git a/web/.gitignore b/web/.gitignore
index 585c62dfb..3dd570b24 100644
--- a/web/.gitignore
+++ b/web/.gitignore
@@ -42,3 +42,4 @@ public/assets
public/uploads
/log/*.out
BUILD_NUMBER
+.byebug_history
diff --git a/web/app/assets/javascripts/hoverMusician.js b/web/app/assets/javascripts/hoverMusician.js
index c8b927cee..59ca14c50 100644
--- a/web/app/assets/javascripts/hoverMusician.js
+++ b/web/app/assets/javascripts/hoverMusician.js
@@ -7,6 +7,7 @@
var logger = context.JK.logger;
var rest = context.JK.Rest();
var hoverSelector = "#musician-hover";
+ var latencyBadgeSelector = '#musician-latency-badge';
var $templateLatency = null;
var sessionUtils = context.JK.SessionUtils;
@@ -91,11 +92,11 @@
full_score: fullScore
});
- var latencyBadge = context._.template(
- $templateLatency.html(),
- $.extend(response, sessionUtils.createLatency(response)),
- {variable: 'data'}
- );
+ // var latencyBadge = context._.template(
+ // $templateLatency.html(),
+ // $.extend(response, sessionUtils.createLatency(response)),
+ // {variable: 'data'}
+ // );
var musicianHtml = context.JK.fillTemplate(template, {
userId: response.id,
@@ -112,7 +113,7 @@
session_display: sessionDisplayStyle,
join_display: joinDisplayStyle,
sessionId: sessionId,
- latency_badge: latencyBadge,
+ // latency_badge: latencyBadge,
//friendAction: response.is_friend ? "removeMusicianFriend" : (response.pending_friend_request ? "" : "sendMusicianFriendRequest"),
friendAction: response.is_friend ? "" : (response.pending_friend_request ? "" : "sendMusicianFriendRequest"),
followAction: response.is_following ? "removeMusicianFollowing" : "addMusicianFollowing",
@@ -130,6 +131,11 @@
$(hoverSelector).css(css);
$(hoverSelector).fadeIn(500);
+
+ bindUserLatencyUpdate(userId);
+ LatencyActions.resolve([userId]);
+
+ bindUserLatencyFail();
})
.fail(function(xhr) {
if(xhr.status >= 500) {
@@ -180,8 +186,77 @@
}
+ function bindUserLatencyUpdate(userId){
+ var latency;
+ $(document).one('user_latency_update', function(e, latencyResp){
+ latency = latencyResp['users'][0];
+ //logger.debug("bindUserLatencyUpdate", latency)
+ if(latency != undefined){
+ if(latency['user_id'] === userId){
+ showLatencyBadge(latency)
+ }
+ }else{
+ showUnknownLatencyBadge(userId);
+ }
+ });
+ }
+
+ function bindUserLatencyFail(){
+ $(document).one('user_latency_fail', function(e, failedUserIds){
+ //logger.debug("bindUserLatencyFail", failedUserIds)
+ if(_.contains(failedUserIds, userId)){
+ showFailedLatencyBadge(userId)
+ }
+ });
+ }
+
+ function showLatencyBadge(latency){
+ var latencyData = sessionUtils.changeLatencyDataStructure(latency);
+ $templateLatency = $("#template-account-session-latency");
+ var latencyBadge = context._.template(
+ $templateLatency.html(),
+ $.extend(latencyData, sessionUtils.createLatency(latencyData)),
+ { variable: 'data' }
+ );
+ $(latencyBadgeSelector).html(latencyBadge)
+ }
+
+ function showFailedLatencyBadge(userId){
+ var failedLatency = {
+ "user_id": userId,
+ "audio_latency": 0,
+ "ars": {
+ "internet_latency": 0,
+ "total_latency": -3.0
+ }
+ };
+ showLatencyBadge(failedLatency);
+ }
+
+ function showUnknownLatencyBadge(userId){
+ var unknownLatency = {
+ "user_id": userId,
+ "audio_latency": 0,
+ "ars": {
+ "internet_latency": 0,
+ "total_latency": -2
+ }
+ };
+ showLatencyBadge(unknownLatency);
+ }
+
+ function unbindUserLatencyUpdate(){
+ $(document).off('user_latency_update');
+ }
+
+ function unbindUserLatencyFail(){
+ $(document).off('user_latency_fail');
+ }
+
this.hideBubble = function() {
- $(hoverSelector).hide();
+ unbindUserLatencyUpdate();
+ unbindUserLatencyFail();
+ $(hoverSelector).hide();
};
this.id = function() {
diff --git a/web/app/assets/javascripts/jam_rest.js b/web/app/assets/javascripts/jam_rest.js
index 99c357923..7769e664b 100644
--- a/web/app/assets/javascripts/jam_rest.js
+++ b/web/app/assets/javascripts/jam_rest.js
@@ -1773,6 +1773,17 @@
});
}
+ function getLatencyToUsers(options) {
+ var id = getId(options);
+ return $.ajax({
+ type: "GET",
+ url: '/api/users/' + id + '/latencies',
+ dataType: "json",
+ contentType: 'application/json',
+ data: options
+ });
+ }
+
function updateAudioLatency(options) {
var id = getId(options);
return $.ajax({
@@ -3204,6 +3215,7 @@
this.cancelSubscription= cancelSubscription;
this.listInvoices = listInvoices;
this.getVideoConferencingRoomUrl = getVideoConferencingRoomUrl;
+ this.getLatencyToUsers = getLatencyToUsers;
return this;
};
})(window, jQuery);
diff --git a/web/app/assets/javascripts/react-components/FindSessionOpen.js.jsx.coffee b/web/app/assets/javascripts/react-components/FindSessionOpen.js.jsx.coffee
index cda48a101..e0f1bd47a 100644
--- a/web/app/assets/javascripts/react-components/FindSessionOpen.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/FindSessionOpen.js.jsx.coffee
@@ -24,7 +24,7 @@ SessionsActions = @SessionsActions
`
How This Page Works
This page will show only public jam sessions.
-
Most recent sessions are shown an the top.
+
Most recent sessions are shown at the top.
This list of public sessions does not auto-update. You will have to push the REFRESH button to see new sessions.
`
else if this.props.mode == 'my'
diff --git a/web/app/assets/javascripts/react-components/actions/LatencyActions.js.coffee b/web/app/assets/javascripts/react-components/actions/LatencyActions.js.coffee
new file mode 100644
index 000000000..2e77f316c
--- /dev/null
+++ b/web/app/assets/javascripts/react-components/actions/LatencyActions.js.coffee
@@ -0,0 +1,7 @@
+context = window
+
+@LatencyActions = Reflux.createActions({
+ resolve: {}
+ fail: {}
+})
+
diff --git a/web/app/assets/javascripts/react-components/stores/LatencyStore.js.coffee b/web/app/assets/javascripts/react-components/stores/LatencyStore.js.coffee
new file mode 100644
index 000000000..c3f12ab83
--- /dev/null
+++ b/web/app/assets/javascripts/react-components/stores/LatencyStore.js.coffee
@@ -0,0 +1,39 @@
+$ = jQuery
+context = window
+logger = context.JK.logger
+rest = new context.JK.Rest()
+
+@LatencyStore = Reflux.createStore(
+ {
+ latencies: []
+
+ listenables: @LatencyActions
+
+ init: ->
+ this.listenTo(context.AppStore, this.onAppInit)
+
+ onAppInit: (@app) ->
+
+ changed: () ->
+ $(document).triggerHandler("user_latency_update", @latencies)
+ @trigger(@latencies)
+
+ onResolve: (user_ids) ->
+ rest.getLatencyToUsers({user_ids: user_ids}).done((response) => @onLoaded(response)).fail((jqXHR) => @onLatencyFail(jqXHR, [user_ids]))
+
+ onLoaded: (response) ->
+ logger.debug("LatencyStore.onLoaded", response);
+ @latencies.push(response)
+ @changed()
+
+ onLatencyFail:(jqXHR, user_ids) ->
+ LatencyActions.fail(user_ids)
+
+ onFail:(user_ids) ->
+ $(document).triggerHandler("user_latency_fail", user_ids)
+ @trigger(user_ids)
+
+ getState:() ->
+ { latencies: @latencies }
+ }
+)
diff --git a/web/app/assets/javascripts/session_utils.js b/web/app/assets/javascripts/session_utils.js
index 6daf85904..cbddaf972 100644
--- a/web/app/assets/javascripts/session_utils.js
+++ b/web/app/assets/javascripts/session_utils.js
@@ -18,7 +18,8 @@
MEDIUM : {description: "FAIR", style: "latency-fair", min: 40.0, max: 70.0},
POOR : {description: "POOR", style: "latency-poor", min: 70.0, max: 100},
UNACCEPTABLE: {description: "UNACCEPTABLE", style: "latency-unacceptable", min: 100, max: 10000000},
- UNKNOWN: {description: "UNKNOWN", style: "latency-unknown", min: -2, max: -2}
+ UNKNOWN: {description: "UNKNOWN", style: "latency-unknown", min: -2, max: -2},
+ FAILED: {description: "FAILED", style: "latency-failed", min: -3, max: -3}
};
sessionUtils.setAutoOpenJamTrack = function(jamTrack) {
@@ -78,6 +79,16 @@
}
}
+ sessionUtils.changeLatencyDataStructure = function(data) {
+ var alteredData = {
+ id: data.user_id,
+ audio_latency: data.audio_latency,
+ full_score: data.ars['total_latency'],
+ internet_score: data.ars['internet_latency']
+ }
+ return alteredData;
+ }
+
sessionUtils.scoreInfo = function(full_score, isSameUser) {
var latencyDescription;
var latencyStyle;
@@ -90,7 +101,19 @@
iconName = 'purple';
description = 'me';
}
- else if (!full_score) {
+ else if (full_score <= LATENCY.FAILED.max) {
+ latencyDescription = LATENCY.FAILED.description;
+ latencyStyle = LATENCY.FAILED.style;
+ iconName = 'gray';
+ description = 'failed';
+ }
+ // else if (!full_score) {
+ // latencyDescription = LATENCY.UNKNOWN.description;
+ // latencyStyle = LATENCY.UNKNOWN.style;
+ // iconName = 'purple';
+ // description = 'missing';
+ // }
+ else if (!full_score || full_score <= LATENCY.UNKNOWN.max) {
latencyDescription = LATENCY.UNKNOWN.description;
latencyStyle = LATENCY.UNKNOWN.style;
iconName = 'purple';
@@ -114,13 +137,13 @@
iconName = 'red';
description = 'poor';
}
- else {
+ else if (full_score > LATENCY.UNACCEPTABLE.min) {
latencyStyle = LATENCY.UNACCEPTABLE.style;
latencyDescription = LATENCY.UNACCEPTABLE.description;
iconName = 'blue';
description = 'unacceptable';
}
-
+
return {
latency_style: latencyStyle,
latency_text: latencyDescription,
@@ -128,6 +151,7 @@
description: description
};
}
+
sessionUtils.createLatency = function(user) {
return sessionUtils.scoreInfo(user.full_score, user.id === context.JK.currentUserId)
}
diff --git a/web/app/assets/stylesheets/client/common.scss b/web/app/assets/stylesheets/client/common.scss
index 5f748b06d..d238498cf 100644
--- a/web/app/assets/stylesheets/client/common.scss
+++ b/web/app/assets/stylesheets/client/common.scss
@@ -48,6 +48,7 @@ $latencyBadgeFair: #cc9900;
$latencyBadgePoor: #980006;
$latencyBadgeUnacceptable: #868686;
$latencyBadgeUnknown: #868686;
+$latencyBadgeFailed: #868686;
$good: #71a43b;
$unknown: #868686;
diff --git a/web/app/assets/stylesheets/client/hoverBubble.scss b/web/app/assets/stylesheets/client/hoverBubble.scss
index fda3967c9..407760f1c 100644
--- a/web/app/assets/stylesheets/client/hoverBubble.scss
+++ b/web/app/assets/stylesheets/client/hoverBubble.scss
@@ -120,4 +120,8 @@
.latency-poor {
background-color:$latencyBadgePoor;
}
+
+ .latency-failed {
+ background-color:$latencyBadgeFailed;
+ }
}
\ No newline at end of file
diff --git a/web/app/assets/stylesheets/client/musician.scss b/web/app/assets/stylesheets/client/musician.scss
index 11c534e90..66ff4ecb8 100644
--- a/web/app/assets/stylesheets/client/musician.scss
+++ b/web/app/assets/stylesheets/client/musician.scss
@@ -129,6 +129,10 @@
background-color:$latencyBadgePoor;
}
+ .latency-failed {
+ background-color:$latencyBadgeFailed;
+ }
+
/**
.latency {
font-size: 15px;
diff --git a/web/app/assets/stylesheets/client/sessionList.scss b/web/app/assets/stylesheets/client/sessionList.scss
index c39ee2fcd..c5df7a844 100644
--- a/web/app/assets/stylesheets/client/sessionList.scss
+++ b/web/app/assets/stylesheets/client/sessionList.scss
@@ -63,6 +63,16 @@ table.findsession-table, table.local-recordings, table.open-jam-tracks, table.op
background-color:$latencyBadgePoor;
text-align:center;
}
+
+ .latency-failed{
+ width: 40px;
+ height: 10px;
+ font-family:Arial, Helvetica, sans-serif;
+ font-weight:200;
+ font-size:11px;
+ background-color:$latencyBadgeFailed;
+ text-align:center;
+ }
}
table.findsession-table, table.local-recordings, table.open-jam-tracks, table.open-backing-tracks, table.cart-items, table.payment-table, table.jamtable {
width:98%;
diff --git a/web/app/assets/stylesheets/web/session_info.scss b/web/app/assets/stylesheets/web/session_info.scss
index 975d9db0c..e3bc7ef52 100644
--- a/web/app/assets/stylesheets/web/session_info.scss
+++ b/web/app/assets/stylesheets/web/session_info.scss
@@ -43,6 +43,10 @@ body.web.session_info {
background-color:$latencyBadgePoor;
}
+ .latency-failed {
+ background-color:$latencyBadgeFailed;
+ }
+
.latency-me {
width: 40px;
height: 10px;
diff --git a/web/app/controllers/api_users_controller.rb b/web/app/controllers/api_users_controller.rb
index 2e78eb826..9ad0f52f2 100644
--- a/web/app/controllers/api_users_controller.rb
+++ b/web/app/controllers/api_users_controller.rb
@@ -937,33 +937,56 @@ class ApiUsersController < ApiController
#fetch latency information from latency-graph serverless
def get_latencies
- query_str = params[:user_ids].split(',').inject(""){|q, id| q.concat("id=#{id}&")}
- latency_url = "#{Rails.application.config.latency_data_host}/dev/user_latencies/#{current_user.id}?#{query_str}"
- url = URI(latency_url)
+ user_ids = params[:user_ids]
+ latency_url = "#{Rails.application.config.latency_data_host}/user_latencies"
+ uri = URI(latency_url)
begin
- http = Net::HTTP.new(url.host, url.port)
+ http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true if Rails.application.config.latency_data_host.start_with?("https://")
- request = Net::HTTP::Get.new(url)
- request["Authorization"] = "Basic #{Rails.application.config.latency_data_host_auth_code}"
- response = http.request(request)
+ req = Net::HTTP::Post.new(uri)
+ req["Authorization"] = "Basic #{Rails.application.config.latency_data_host_auth_code}"
+ req["Content-Type"] = "application/json"
+ req.body = {
+ my_user_id: current_user.id,
+ my_public_ip: request.remote_ip,
+ my_device_id: nil,
+ my_client_id: nil,
+ users: user_ids
+ }.to_json
+
+ response = http.request(req)
+ #debugger
+
if response.is_a?(Net::HTTPOK) || response.is_a?(Net::HTTPSuccess)
render json: response.body, status: 200
else
- Bugsnag.notify(exception) do |report|
- report.severity = "error"
+ logger.debug("Latency response failed: #{response}")
+ Bugsnag.notify("LatencyResponseFailed") do |report|
+ report.severity = "faliure"
report.add_tab(:latency, {
user_id: current_user.id,
name: current_user.name,
user_ids: params[:user_ids],
url: latency_url,
- body: response.body
+ code: response.code,
+ body: response.body,
})
end
- render json: {}, status: 422
+ render json: { user_ids: params[:user_ids] }, status: 422
end
- rescue
- Bugsnag.notify("Latency server returned code: #{response.code}")
- render json: {}, status: 500
+ rescue => exception
+ #debugger
+ logger.debug("Latency exception: #{exception.message}")
+ Bugsnag.notify(exception) do |report|
+ report.severity = "error"
+ report.add_tab(:latency, {
+ user_id: current_user.id,
+ name: current_user.name,
+ user_ids: params[:user_ids],
+ url: latency_url,
+ })
+ end
+ render json: { user_ids: params[:user_ids] }, status: 500
end
end
diff --git a/web/app/views/clients/_hoverMusician.html.erb b/web/app/views/clients/_hoverMusician.html.erb
index bc88742b8..435f2ec4d 100644
--- a/web/app/views/clients/_hoverMusician.html.erb
+++ b/web/app/views/clients/_hoverMusician.html.erb
@@ -117,7 +117,8 @@
{biography}
- Your latency to {first_name} is: {latency_badge}
+ Your latency to {first_name} is:
+
diff --git a/web/bin/test b/web/bin/test
index b08d6a26e..513c7a260 100755
--- a/web/bin/test
+++ b/web/bin/test
@@ -10,6 +10,8 @@ tests=(
"spec/features/affiliate_program_spec.rb"
"spec/features/affiliate_visit_tracking_spec.rb"
"spec/features/affiliate_referral_spec.rb"
+ "spec/features/musician_hover_spec_1.rb"
+ "spec/features/musician_hover_spec_2.rb"
"spec/controllers/api_affiliate_controller_spec.rb"
)
diff --git a/web/config/environments/development.rb b/web/config/environments/development.rb
index 478424b43..c0b3bf258 100644
--- a/web/config/environments/development.rb
+++ b/web/config/environments/development.rb
@@ -114,6 +114,6 @@ SampleApp::Application.configure do
config.video_conferencing_host = "https://webrtc-demo.jamkazam.com"
config.use_video_conferencing_server = true
- config.latency_data_host = "http://localhost:4001"
+ config.latency_data_host = "http://localhost:4001/dev"
config.latency_data_host_auth_code = "c2VydmVyOnBhc3N3b3Jk"
end
diff --git a/web/config/environments/test.rb b/web/config/environments/test.rb
index e2627130e..61e785a9f 100644
--- a/web/config/environments/test.rb
+++ b/web/config/environments/test.rb
@@ -133,7 +133,7 @@ SampleApp::Application.configure do
config.video_conferencing_host = "https://webrtc-demo.jamkazam.com"
config.use_video_conferencing_server = false
- config.latency_data_host = "http://localhost:4001"
+ config.latency_data_host = "http://localhost:4001/test"
config.latency_data_host_auth_code = "c2VydmVyOnBhc3N3b3Jk"
end
diff --git a/web/spec/controllers/api_users_controller_spec.rb b/web/spec/controllers/api_users_controller_spec.rb
index f019ea6c3..f1daba6a2 100644
--- a/web/spec/controllers/api_users_controller_spec.rb
+++ b/web/spec/controllers/api_users_controller_spec.rb
@@ -314,12 +314,13 @@ describe ApiUsersController, type: :controller do
describe "get_latencies" do
let(:user1) { FactoryGirl.create(:user) }
let(:user2) { FactoryGirl.create(:user) }
- let(:latency_data_uri) { /\/dev\/user_latencies\// }
- let(:response_body) { File.open('./spec/fixtures/latency_reponse.json') }
+ let(:latency_data_uri) { /\S+\/dev\/user_latencies/ }
+ let(:response_body) { File.open('./spec/fixtures/latency_response.json') }
it "fetch latency graph data" do
- stub_request(:get, latency_data_uri)
+ stub_request(:post, latency_data_uri)
.to_return( body: response_body, status: 200)
+
get :get_latencies, id: user.id, user_ids: [user1, user2].map(&:id).join(',')
response.should be_success
JSON.parse(response.body)['users'].size.should eq(2)
diff --git a/web/spec/features/musician_hover_spec_1.rb b/web/spec/features/musician_hover_spec_1.rb
new file mode 100644
index 000000000..c0c877eed
--- /dev/null
+++ b/web/spec/features/musician_hover_spec_1.rb
@@ -0,0 +1,75 @@
+require 'spec_helper'
+require 'webmock/rspec'
+
+#NOTE: The rest of the tests related to musician latency badge are in
+#musician_hover_spec_2.rb file. For some uncertain issue getting all these
+#tests in a single file doesn't work because some of them fail without a reason.
+#Probably because of webmock behaving wiredly.
+
+describe "Musician Hover", :js => true, :type => :feature, :capybara_feature => true do
+ let(:user1) { FactoryGirl.create(:user) }
+ let(:user2) { FactoryGirl.create(:user) }
+
+ let(:latency_data_uri) { /\S+\/dev\/user_latencies/ }
+
+ before do
+ Capybara.default_max_wait_time = 30 # these tests are SLOOOOOW
+ WebMock.disable_net_connect!(allow_localhost: true)
+ end
+
+ before(:each) do
+ fast_signin(user1, "/client")
+ wait_until_curtain_gone
+ end
+
+ describe "Latency badge" do
+ it "show ME (same user)" do
+ response_body = mock_latency_response(user1, 1.0) #sessionUtils.LATENCY.UNKNOWN: {description: "UNKNOWN", style: "latency-unknown", min: -2, max: -2}
+ stub_request(:post, latency_data_uri)
+ .with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'})
+ .to_return( body: response_body, status: 200)
+
+ site_search(user1.first_name, expand: true)
+ find("#search-results a[user-id=\"#{user1.id}\"][hoveraction=\"musician\"]", text: user1.name).hover_intent
+ find('h3', text: user1.name)
+ find("#musician-latency-badge div.latency", text: 'ME')
+ end
+
+ it "show FAILED" do
+ stub_request(:post, latency_data_uri)
+ .with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'})
+ .to_raise("some error")
+
+ site_search(user2.first_name, expand: true)
+ find("#search-results a[user-id=\"#{user2.id}\"][hoveraction=\"musician\"]", text: user2.name).hover_intent
+ find('h3', text: user2.name)
+ find("#musician-latency-badge", text: 'FAILED')
+ end
+
+ it "show UNKNOWN" do
+ response_body = mock_latency_response(user2, nil) #sessionUtils.LATENCY.UNKNOWN: {description: "UNKNOWN", style: "latency-unknown", min: -2, max: -2}
+ stub_request(:post, latency_data_uri)
+ .with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'})
+ .to_return( body: response_body, status: 200)
+
+ site_search(user2.first_name, expand: true)
+ find("#search-results a[user-id=\"#{user2.id}\"][hoveraction=\"musician\"]", text: user2.name).hover_intent
+ find('h3', text: user2.name)
+ find("#musician-latency-badge div.latency", text: 'UNKNOWN')
+ end
+
+ it "show GOOD" do
+ response_body = mock_latency_response(user2, 1.0) #sessionUtils.LATENCY.GOOD : {description: "GOOD", style: "latency-good", min: 0.0, max: 40.0},
+ stub_request(:post, latency_data_uri)
+ .with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'})
+ .to_return( body: response_body, status: 200)
+
+ site_search(user2.first_name, expand: true)
+ find("#search-results a[user-id=\"#{user2.id}\"][hoveraction=\"musician\"]", text: user2.name).hover_intent
+ find('h3', text: user2.name)
+ find("#musician-latency-badge div.latency", text: 'GOOD')
+ end
+
+ end
+
+end
diff --git a/web/spec/features/musician_hover_spec_2.rb b/web/spec/features/musician_hover_spec_2.rb
new file mode 100644
index 000000000..66be2abbc
--- /dev/null
+++ b/web/spec/features/musician_hover_spec_2.rb
@@ -0,0 +1,59 @@
+require 'spec_helper'
+require 'webmock/rspec'
+
+describe "Musician Hover", :js => true, :type => :feature, :capybara_feature => true do
+ let(:user1) { FactoryGirl.create(:user) }
+ let(:user2) { FactoryGirl.create(:user) }
+
+ let(:latency_data_uri) { /\S+\/dev\/user_latencies/ }
+
+ before do
+ Capybara.default_max_wait_time = 30 # these tests are SLOOOOOW
+ WebMock.disable_net_connect!(allow_localhost: true)
+ end
+
+ before(:each) do
+ fast_signin(user1, "/client")
+ wait_until_curtain_gone
+ end
+
+ describe "Latency badge" do
+ it "show POOR" do
+ response_body = mock_latency_response(user2, 71.0) #sessionUtils.LATENCY.POOR : {description: "POOR", style: "latency-poor", min: 70.0, max: 100},
+ stub_request(:post, latency_data_uri)
+ .with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'})
+ .to_return( body: response_body, status: 200)
+
+ site_search(user2.first_name, expand: true)
+ find("#search-results a[user-id=\"#{user2.id}\"][hoveraction=\"musician\"]", text: user2.name).hover_intent
+ find('h3', text: user2.name)
+ find("#musician-latency-badge div.latency", text: 'POOR')
+ end
+
+ it "show FAIR" do
+ response_body = mock_latency_response(user2, 41.0) #sessionUtils.LATENCY.FAIR : {description: "FAIR", style: "latency-fair", min: 40.0, max: 70.0},
+ stub_request(:post, latency_data_uri)
+ .with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'})
+ .to_return( body: response_body, status: 200)
+
+ site_search(user2.first_name, expand: true)
+ find("#search-results a[user-id=\"#{user2.id}\"][hoveraction=\"musician\"]", text: user2.name).hover_intent
+ find('h3', text: user2.name)
+ find("#musician-latency-badge div.latency", text: 'FAIR')
+ end
+
+ it "show UNACCEPTABLE", focus: true do
+ response_body = mock_latency_response(user2, 101.0) #sessionUtils.LATENCY.UNACCEPTABLE : {description: "UNACCEPTABLE", style: "latency-unacceptable", min: 100.0, max: 10000000},
+ stub_request(:post, latency_data_uri)
+ .with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'})
+ .to_return( body: response_body, status: 200)
+
+ site_search(user2.first_name, expand: true)
+ find("#search-results a[user-id=\"#{user2.id}\"][hoveraction=\"musician\"]", text: user2.name).hover_intent
+ find('h3', text: user2.name)
+ find("#musician-latency-badge div.latency", text: 'UNACCEPTABLE')
+ end
+
+ end
+
+end
diff --git a/web/spec/fixtures/latency_reponse.json b/web/spec/fixtures/latency_response.json
similarity index 100%
rename from web/spec/fixtures/latency_reponse.json
rename to web/spec/fixtures/latency_response.json
diff --git a/web/spec/support/utilities.rb b/web/spec/support/utilities.rb
index be5bdc431..665e9ec72 100644
--- a/web/spec/support/utilities.rb
+++ b/web/spec/support/utilities.rb
@@ -795,4 +795,37 @@ end
def nav_profile_history(user)
visit Nav.profile(user)
find('#history-link').trigger(:click)
+end
+
+def mock_latency_response(user, latency)
+ resp = nil
+ if latency
+ resp = {
+ "users": [
+ {
+ "user_id": user.id,
+ "first_name": user.first_name,
+ "last_name": user.last_name,
+ "audio_latency": 4.0,
+ "audio_latency_unknown": false,
+ "ars": {
+ "internet_latency": latency,
+ "total_latency": latency
+ },
+ "p2p": {
+ "internet_latency": latency,
+ "total_latency": latency
+ },
+ "wifi": false
+ }
+ ],
+ "my_audio_latency": 4.0,
+ "my_audio_latency_unknown": false
+ }
+ else
+ resp = {
+ "users": []
+ }
+ end
+ return resp.to_json
end
\ No newline at end of file
diff --git a/websocket-gateway/.gitignore b/websocket-gateway/.gitignore
index f2b32455d..bb21c2317 100644
--- a/websocket-gateway/.gitignore
+++ b/websocket-gateway/.gitignore
@@ -25,3 +25,4 @@ log/*
target
vendor
BUILD_NUMBER
+.byebug_history
diff --git a/websocket-gateway/Gemfile.lock b/websocket-gateway/Gemfile.lock
index fb4987b4f..cd6f896f0 100644
--- a/websocket-gateway/Gemfile.lock
+++ b/websocket-gateway/Gemfile.lock
@@ -578,6 +578,7 @@ DEPENDENCIES
newrelic_rpm
nokogiri (= 1.10.10)
oj (= 3.1.3)
+ pg (= 0.17.1)
postgres-copy
postgres_ext
protected_attributes