Merge branch 'develop' into feature/ratings

This commit is contained in:
Steven Miers 2015-07-21 16:56:40 -05:00
commit 35ec59ff97
39 changed files with 253 additions and 110 deletions

View File

@ -17,7 +17,8 @@ describe 'Musician Search Model' do
describe "creates search obj" do
before(:all) do
User.delete_all
Score.delete_all
Score.connection.execute('delete from current_network_scores').check
Score.connection.execute('delete from scores').check
end
it "associates to user" do
@ -235,7 +236,7 @@ describe 'Musician Search Model' do
Score.createx(2, 'b', 2, 4, 'd', 4, 70)
end
it "sorts by latency" do
it "sorts by latency", intermittent: true do
search.update_json_value(MusicianSearch::KEY_SORT_ORDER, MusicianSearch::SORT_VALS[0])
results = search.do_search
expect(results[0].id).to eq(@user1.id) # HAS FAILED HERE TOO

View File

@ -195,7 +195,9 @@ describe Sale do
end
it "for a normally priced jam track" do
it "for a normally priced jam track", intermittent: true do
# intermittent: sometimes recurly won't mark it 'collected' soon enough for the test to pass
user.has_redeemable_jamtrack = false
user.save!
shopping_cart = ShoppingCart.create user, jamtrack, 1, false
@ -236,8 +238,6 @@ describe Sale do
sale_line_item.recurly_adjustment_credit_uuid.should be_nil
sale_line_item.recurly_adjustment_uuid.should eq(user.jam_track_rights.last.recurly_adjustment_uuid)
# sometimes recurly won't mark it 'collected' immediately
sleep 1
# verify subscription is in Recurly
recurly_account = client.get_account(user)

View File

@ -14,7 +14,7 @@ require 'resque_failed_job_mailer'
# to prevent embedded resque code from forking
ENV['FORK_PER_JOB'] = 'false'
IS_BUILD_SERVER = !ENV['BUILD_SERVER'].nil?
# recreate test database and migrate it
SpecDb::recreate_database
@ -85,12 +85,13 @@ end
config.run_all_when_everything_filtered = true
config.filter_run :focus
config.formatter = :documentation
#config.formatter = :documentation
# you can mark a test as slow so that developers won't commonly hit it, but build server will http://blog.davidchelimsky.net/2010/06/14/filtering-examples-in-rspec-2/
config.filter_run_excluding slow: true unless run_tests? :slow
config.filter_run_excluding aws: true unless run_tests? :aws
config.filter_run_excluding intermittent: true if IS_BUILD_SERVER
config.before(:suite) do
DatabaseCleaner.strategy = :transaction

View File

@ -98,9 +98,10 @@ source 'https://rails-assets.org' do
gem 'rails-assets-classnames'
end
group :development, :production do
gem 'rack-timeout'
end
#group :development, :production do
# gem 'rack-timeout'
#end
group :development, :test do
gem 'rspec-rails', '2.14.2'
gem "activerecord-import", "~> 0.4.1"

View File

@ -88,8 +88,8 @@ context.JK.AccountJamTracks = class AccountJamTracks
context.location = '/client#/session/' + newSessionId
# Re-loading the session settings will cause the form to reset with the right stuff in it.
# This is an extra xhr call, but it keeps things to a single codepath
loadSessionSettings()
context.JK.GA.trackSessionCount data.musician_access, data.fan_access, invitationCount
#loadSessionSettings()
context.JK.GA.trackSessionCount data.musician_access, data.fan_access, 0
context.JK.GA.trackSessionMusicians context.JK.GA.SessionCreationTypes.create
).fail (jqXHR) =>
handled = false

View File

@ -4,10 +4,10 @@ $ = jQuery
context = window
context.JK ||= {};
broadcastActions = @BroadcastActions
logger = context.JK.logger
context.JK.ClientInit = class ClientInit
constructor: () ->
@logger = context.JK.logger
@gearUtils = context.JK.GearUtils
@ALERT_NAMES = context.JK.ALERT_NAMES;
@lastCheckedBroadcast = null
@ -21,9 +21,11 @@ context.JK.ClientInit = class ClientInit
this.watchBroadcast()
checkBroadcast: () =>
broadcastActions.load.triggerPromise().catch(() ->
false
)
promise = broadcastActions.load.triggerPromise()
if promise
promise.catch(() ->
false
)
watchBroadcast: () =>

View File

@ -57,11 +57,11 @@
})
.fail(function(xhr, textStatus, errorMessage) {
if (xhr.status === 404) {
logger.warn("unable to list active sessions (404)")
logger.warn("unable to list active sessions (404) " + + JSON.stringify(xhr.responseText))
// swallow 404
}
else {
logger.warn("unable to list active sessions")
logger.warn("unable to list active sessions: " + JSON.stringify(xhr.responseText))
app.ajaxError(xhr, textStatus, errorMessage);
}
})
@ -82,6 +82,7 @@
else {
app.ajaxError(xhr, textStatus, errorMessage);
}
logger.warn("unable to list scheduled sessions: " + JSON.stringify(xhr.responseText))
})
.always(function() {
$ssSpinner.hide();

View File

@ -4,6 +4,7 @@
//= require ./react-components/stores/RecordingStore
//= require ./react-components/stores/SessionStore
//= require ./react-components/stores/MixerStore
//= require ./react-components/stores/JamTrackStore
//= require ./react-components/stores/SessionNotificationStore
//= require ./react-components/stores/MediaPlaybackStore
//= require ./react-components/stores/SessionMyTracksStore

View File

@ -77,7 +77,7 @@ mixins.push(Reflux.listenTo(MediaPlaybackStore, 'onMediaStateChanged'))
</div>`
windowUnloaded: () ->
SessionActions.closeMedia() unless window.DontAutoCloseMedia
SessionActions.closeMedia(false) unless window.DontAutoCloseMedia
componentDidMount: () ->

View File

@ -1,5 +1,5 @@
context = window
MIX_MODES = context.JK.MIX_MODES
MixerActions = @MixerActions
@SessionBackingTrack = React.createClass({
@ -70,20 +70,23 @@ MixerActions = @MixerActions
$mute = $root.find('.track-icon-mute')
$pan = $root.find('.track-icon-pan')
context.JK.interactReactBubble(
$mute,
'SessionTrackVolumeHover',
() =>
{mixers:@mixers()}
,
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
context.JK.interactReactBubble(
$pan,
'SessionTrackPanHover',
() =>
{mixers:@mixers()}
,
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
if @props.isOpener || @props.mode == MIX_MODES.MASTER
context.JK.interactReactBubble(
$mute,
'SessionTrackVolumeHover',
() =>
{mixers:@mixers()}
,
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
context.JK.interactReactBubble(
$pan,
'SessionTrackPanHover',
() =>
{mixers:@mixers()}
,
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
else
context.JK.helpBubble($mute, 'personal-media-track', {}, {positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
context.JK.helpBubble($pan, 'personal-media-track', {}, {positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
})

View File

@ -1,5 +1,5 @@
context = window
MIX_MODES = context.JK.MIX_MODES
MixerActions = @MixerActions
@SessionJamTrack = React.createClass({
@ -49,7 +49,7 @@ MixerActions = @MixerActions
`<div className={componentClasses}>
<div className="session-track-contents">
<div className="name">{this.props.part}</div>
<div className="name">{this.props.trackName}</div>
<div className="track-controls">
<SessionTrackVU orientation="horizontal" lightCount={4} lightWidth={17} lightHeight={3} side="best" mixers={mixers} />
<div className="track-buttons">
@ -70,20 +70,23 @@ MixerActions = @MixerActions
$mute = $root.find('.track-icon-mute')
$pan = $root.find('.track-icon-pan')
context.JK.interactReactBubble(
$mute,
'SessionTrackVolumeHover',
() =>
{mixers:@mixers()}
,
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
context.JK.interactReactBubble(
$pan,
'SessionTrackPanHover',
() =>
{mixers:@mixers()}
,
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
if @props.isOpener || @props.mode == MIX_MODES.MASTER
context.JK.interactReactBubble(
$mute,
'SessionTrackVolumeHover',
() =>
{mixers:@mixers()}
,
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
context.JK.interactReactBubble(
$pan,
'SessionTrackPanHover',
() =>
{mixers:@mixers()}
,
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
else
context.JK.helpBubble($mute, 'personal-media-track', {}, {positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
context.JK.helpBubble($pan, 'personal-media-track', {}, {positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
})

View File

@ -1,6 +1,7 @@
context = window
rest = context.JK.Rest()
SessionActions = @SessionActions
JamTrackActions = @JamTrackActions
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
MIX_MODES = context.JK.MIX_MODES
EVENTS = context.JK.EVENTS
@ -8,7 +9,16 @@ ChannelGroupIds = context.JK.ChannelGroupIds
@SessionMediaTracks = React.createClass({
mixins: [@SessionMediaTracksMixin, Reflux.listenTo(@SessionMediaTracksStore,"onInputsChanged"), Reflux.listenTo(@AppStore,"onAppInit")]
mixins: [@SessionMediaTracksMixin,
Reflux.listenTo(@SessionMediaTracksStore,"onInputsChanged"),
Reflux.listenTo(@AppStore,"onAppInit"),
Reflux.listenTo(@JamTrackStore, "onJamTrackStateChanged")]
onJamTrackStateChanged: (jamTrack) ->
if jamTrack?
@loadJamTrack(jamTrack)
else
SessionActions.closeMedia(true)
inputsChangedProcessed: (state) ->
@ -27,11 +37,10 @@ ChannelGroupIds = context.JK.ChannelGroupIds
@state.childWindow.DontAutoCloseMedia = true
@state.childWindow.close()
closeAudio: (e) ->
e.preventDefault()
SessionActions.closeMedia()
SessionActions.closeMedia(false)
cancelDownloadJamTrack: (e) ->
e.preventDefault()
@ -103,8 +112,7 @@ ChannelGroupIds = context.JK.ChannelGroupIds
@app.layout.showDialog('open-jam-track-dialog').one(EVENTS.DIALOG_CLOSED, (e, data) =>
# once the dialog is closed, see if the user has a jamtrack selected
if !data.canceled && data.result.jamTrack
@loadJamTrack(data.result.jamTrack)
JamTrackActions.open(data.result.jamTrack)
else
logger.debug("OpenJamTrack dialog closed with no selection; ignoring", data)
)

View File

@ -1,6 +1,7 @@
context = window
logger = context.JK.logger
MixerActions = @MixerActions
MIX_MODES = context.JK.MIX_MODES
@SessionMetronome = React.createClass({
@ -31,6 +32,7 @@ MixerActions = @MixerActions
componentClasses = classNames({
"session-track" : true
"metronome" : true
"no-mixer" : @props.mode == MIX_MODES.MASTER # show it as disabled if in master mode
})
pan = if mixers.mixer? then mixers.mixer?.pan else 0
@ -41,6 +43,7 @@ MixerActions = @MixerActions
}
`<div className={componentClasses}>
<div className="disabled-track-overlay" />
<div className="session-track-contents">
<div className="name">Metronome</div>
<div className="track-controls">
@ -61,16 +64,21 @@ MixerActions = @MixerActions
$root = $(this.getDOMNode())
$topParent = $root.closest('.top-parent')
$mute = $root.find('.track-icon-mute')
$pan = $root.find('.track-icon-pan')
if @props.mode
context.JK.helpBubble($root.find('.disabled-track-overlay'), 'master-metronome-notice', {}, {positions:['top'], offsetParent: $topParent})
context.JK.interactReactBubble(
$mute,
'SessionTrackVolumeHover',
() =>
{mixers:@mixers()}
,
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
{width:235, positions:['right', 'left'], offsetParent:$topParent})
context.JK.interactReactBubble(
$pan,
@ -78,6 +86,6 @@ MixerActions = @MixerActions
() =>
{mixers:@mixers()}
,
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
{width:331, positions:['right', 'left'], offsetParent:$topParent})
})

View File

@ -40,7 +40,7 @@ MixerActions = @MixerActions
`<div className="session-track my-track">
<div className="disabled-track-overlay" />
<div className="session-track-contents">
<div className="name">{this.props.name}</div>
<div className="name">{this.props.trackName}</div>
<div className="track-avatar"><img src={this.props.photoUrl}/></div>
<div className="track-instrument"><img height="45" src={this.props.instrumentIcon} width="45" /></div>
<div className="track-controls">

View File

@ -51,7 +51,7 @@ MixerActions = @MixerActions
`<div className={componentClasses}>
<div className="disabled-track-overlay" />
<div className="session-track-contents">
<div className="name">{this.props.name}</div>
<div className="name">{this.props.trackName}</div>
<div className="track-avatar"><img src={this.props.photoUrl}/></div>
<div className="track-instrument"><img height="45" src={this.props.instrumentIcon} width="45" /></div>
<div className="track-controls">

View File

@ -16,9 +16,8 @@ ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
for participant in session.otherParticipants()
name = participant.user.name
tracks = []
name = participant.user.name;
firstTrack = participant.tracks[0]
hasMixer = false
@ -34,13 +33,17 @@ ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
# todo: sessionModel.setAudioEstablished
instrumentIcon = context.JK.getInstrumentIcon45(firstTrack.instrument_id)
instrumentDescription = firstTrack.instrument
photoUrl = context.JK.resolveAvatarUrl(participant.user.photo_url)
name = "#{name}: #{instrumentDescription}"
participantState = {
participant: participant,
tracks: tracks,
name: name,
trackName: name
instrumentIcon: instrumentIcon,
photoUrl: photoUrl,
hasMixer: hasMixer,

View File

@ -1,5 +1,5 @@
context = window
MIX_MODES = context.JK.MIX_MODES
MixerActions = @MixerActions
@SessionRecordedTrack = React.createClass({
@ -70,20 +70,24 @@ MixerActions = @MixerActions
$mute = $root.find('.track-icon-mute')
$pan = $root.find('.track-icon-pan')
context.JK.interactReactBubble(
$mute,
'SessionTrackVolumeHover',
() =>
{mixers:@mixers()}
,
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
if @props.isOpener || @props.mode == MIX_MODES.MASTER
context.JK.interactReactBubble(
$mute,
'SessionTrackVolumeHover',
() =>
{mixers:@mixers()}
,
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
context.JK.interactReactBubble(
$pan,
'SessionTrackPanHover',
() =>
{mixers:@mixers()}
,
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
context.JK.interactReactBubble(
$pan,
'SessionTrackPanHover',
() =>
{mixers:@mixers()}
,
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
else
context.JK.helpBubble($mute, 'personal-media-track', {}, {positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
context.JK.helpBubble($pan, 'personal-media-track', {}, {positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
})

View File

@ -0,0 +1,7 @@
context = window
@JamTrackActions = Reflux.createActions({
open: {}
close: {}
})

View File

@ -192,6 +192,20 @@ MIX_MODES = context.JK.MIX_MODES;
@mediaSummary.mediaOpen = mediaOpenSummary
# figure out if we opened any media
isOpener = false
if @mediaSummary.recordingOpen
isOpener = @recordedTracks[0].isOpener
else if @mediaSummary.jamTrackOpen
isOpener = @jamTracks[0].isOpener
else if @mediaSummary.backingTrackOpen
isOpener = @backingTracks[0].isOpener
@mediaSummary.isOpener = isOpener
# this method is pretty complicated because it forks on a key bit of state:
# sessionModel.isPlayingRecording()
# a backing track opened as part of a recording has a different behavior and presence on the server (recording.recorded_backing_tracks)
@ -324,10 +338,17 @@ MIX_MODES = context.JK.MIX_MODES;
instrumentIcon = context.JK.getInstrumentIcon24(oneOfTheTracks.instrument.id);
part = oneOfTheTracks.part
part = '' unless name?
instrumentName = oneOfTheTracks.instrument.description
if part?
trackName = "#{instrumentName}: #{part}"
else
trackName = instrumentName
data =
name: jamTrackName
trackName: trackName
part: part
isOpener: isOpener
instrumentIcon: instrumentIcon
@ -344,7 +365,8 @@ MIX_MODES = context.JK.MIX_MODES;
return recordedTracks unless @recordingTrackMixers.length > 0
serverRecordedTracks = @session.recordedTracks()
logger.debug("@recordingTrackMixers[0].group_id", @recordingTrackMixers[0].group_id)
isOpener = @recordingTrackMixers[0].group_id == ChannelGroupIds.MediaTrackGroup
# using the server's info in conjuction with the client's, draw the recording tracks

View File

@ -31,6 +31,11 @@ logger = context.JK.logger
metronomeIsShowing = mixers.metronome?
if mixers.mediaSummary.isOpener
mediaCategoryMixer = mixers.getMediaCategoryMixer(@props.mode)
else
mediaCategoryMixer = mixers.getUserMediaCategoryMixer(@props.mode)
state =
isRecording: session.isRecording
mediaSummary: mixers.mediaSummary
@ -38,7 +43,7 @@ logger = context.JK.logger
jamTracks: mixers.jamTracks
recordedTracks: mixers.recordedTracks
metronome: mixers.metronome
mediaCategoryMixer: mixers.getMediaCategoryMixer(@props.mode)
mediaCategoryMixer: mediaCategoryMixer
recordingName: mixers.recordingName()
jamTrackName: mixers.jamTrackName()
metronomeIsShowing: metronomeIsShowing

View File

@ -35,7 +35,8 @@ context = window
instrumentIcon = context.JK.getInstrumentIcon45(track.instrument_id);
tracks.push({track: track, mixerFinder: mixerFinder, mixers: mixerData, name: name, instrumentIcon: instrumentIcon, photoUrl: photoUrl, clientId: participant.client_id})
trackName = "#{name}: #{track.instrument}"
tracks.push({track: track, mixerFinder: mixerFinder, mixers: mixerData, name: name, trackName: trackName, instrumentIcon: instrumentIcon, photoUrl: photoUrl, clientId: participant.client_id})
else

View File

@ -0,0 +1,34 @@
$ = jQuery
context = window
logger = context.JK.logger
rest = context.JK.Rest()
EVENTS = context.JK.EVENTS
JamTrackActions = @JamTrackActions
@JamTrackStore = Reflux.createStore(
{
listenables: JamTrackActions
jamTrack: null
init: ->
# Register with the app store to get @app
this.listenTo(context.AppStore, this.onAppInit)
onAppInit: (app) ->
@app = app
onOpen: (jamTrack) ->
if @jamTrack?
@app.notify({text: 'Unable to open JamTrack because another one is already open.'})
return
@jamTrack = jamTrack
this.trigger(@jamTrack)
onClose: () ->
@jamTrack = null
this.trigger(@jamTrack)
}
)

View File

@ -5,7 +5,7 @@ rest = context.JK.Rest()
EVENTS = context.JK.EVENTS
MIX_MODES = context.JK.MIX_MODES
JamTrackActions = @JamTrackActions
SessionActions = @SessionActions
RecordingActions = @RecordingActions
NotificationActions = @NotificationActions
@ -203,8 +203,8 @@ NotificationActions = @NotificationActions
@sessionPageEnterDeferred = null
onCloseMedia: () ->
# codeInitiated means the user did not initiate this
onCloseMedia: (codeInitiated) ->
logger.debug("SessionStore: onCloseMedia")
if @helper.recordedTracks()
@ -216,7 +216,7 @@ NotificationActions = @NotificationActions
else if @helper.isMetronomeOpen()
@closeMetronomeTrack()
else
logger.error("don't know how to close open media");
logger.error("don't know how to close open media") unless codeInitiated
closeJamTrack: () ->
logger.debug("closing jam track");
@ -244,6 +244,7 @@ NotificationActions = @NotificationActions
)
context.jamClient.JamTrackStopPlay()
JamTrackActions.close()
onOpenBackingTrack: (result) ->
@ -766,9 +767,10 @@ NotificationActions = @NotificationActions
.done((response) =>
logger.debug("jamtrack opened")
# now actually load the jamtrack
# TODO
context.SessionActions.updateSession.trigger(response);
# context.JK.CurrentSessionModel.updateSession(response);
# loadJamTrack(jamTrack);
JamTrackActions.open(jamTrack)
)
.fail((jqXHR) =>
@app.notifyServerError(jqXHR, "Unable to Open JamTrack For Playback")
@ -969,7 +971,7 @@ NotificationActions = @NotificationActions
leaveSession: () ->
if @joinDeferred?.state() == 'resolved'
if !@joinDeferred? || @joinDeferred?.state() == 'resolved'
deferred = new $.Deferred()
@recordingModel.stopRecordingIfNeeded()
@ -1040,7 +1042,9 @@ NotificationActions = @NotificationActions
@controlsLockedForJamTrackRecording = false
@openBackingTrack = null
@downloadingJamTrack = false
@sessionUtils.setAutoOpenJamTrack(null)
JamTrackActions.close()
NotificationActions.sessionEnded()
$(context.AppStore).triggerHandler('SessionEnded')

View File

@ -135,11 +135,11 @@
}
if(type == 'left') {
logger.debug("adding left lights")
//logger.debug("adding left lights")
found.leftLights = lights;
}
else {
logger.debug("adding right lights");
//logger.debug("adding right lights");
found.rightLights = lights;
}
@ -154,7 +154,7 @@
return
}
else {
logger.debug("unregistering " + fqId + ", " + registrations.length)
//logger.debug("unregistering " + fqId + ", " + registrations.length)
}
var origLength = registrations.length;
@ -163,13 +163,13 @@
if(isMatch) {
// found a registration that matches
logger.debug("removing matching ptr", element.ptr)
//logger.debug("removing matching ptr", element.ptr)
element.ptrCount--;
// keep the registration if any ptr's still left
var keepRegistration = element.ptrCount > 0;
if(!keepRegistration) {
logger.debug("getting rid of the registration; no more ptrs");
//logger.debug("getting rid of the registration; no more ptrs");
}
return keepRegistration;
}

View File

@ -122,7 +122,6 @@ $session-screen-divider: 1190px;
@include border_box_sizing;
float: left;
width: 33%;
border-right: 1px solid #4c4c4c;
padding: 10px;
height: 100%;
margin-bottom: 15px;
@ -199,6 +198,9 @@ $session-screen-divider: 1190px;
top:180px;
}
border-right: 1px solid #4c4c4c;
margin-bottom:10px;
margin-top:10px;
}
p {

View File

@ -12,10 +12,18 @@
position:relative;
@include border_box_sizing;
&:nth-child(1) {
margin-top:0;
}
.name {
width: 100%;
margin-bottom: 6px;
@include labelFont;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.track-avatar {
@ -67,6 +75,7 @@
width: 100%;
height: 100%;
opacity:0.5;
z-index:1;
}
}

View File

@ -15,14 +15,15 @@
.dialog-inner {
padding: 10px 20px;
width:100%;
box-sizing:border-box;
p.notice {
width:800px;
line-height:125%;
}
h2 {
font-size:24px;
font-weight:600;
}
}
@ -42,13 +43,15 @@
overflow-x: hidden;
overflow-y: auto;
width: 100%;
padding: 0 15px 0 0;
padding: 0 15px 0 15px;
@include border_box_sizing;
left: 0;
right: 0;
bottom:0;
position:absolute;
top: 40px;
border-right: 1px solid #4c4c4c;
margin-top:10px;
}
.close-button {

View File

@ -53,6 +53,11 @@ else
child(:tracks => :tracks) {
attributes :id, :connection_id, :instrument_id, :sound, :client_track_id, :client_resource_id, :updated_at
node :instrument do |track|
track.instrument.description
end
}
child(:backing_tracks => :backing_tracks) {

View File

@ -310,3 +310,11 @@ script type="text/template" id="template-help-jamtrack-browse-master-mix"
script type="text/template" id="template-help-jamtrack-browse-cta"
.jamtrack-browse-cta.big-help
p Click to select your first free JamTrack!
script type="text/template" id="template-help-master-metronome-notice"
.master-metronome-notice
p The metronome does not produce any sound in the master mix.
script type="text/template" id="template-help-personal-media-track"
.personal-media-track
p Only the person who opened the audio track can modify volume and pan.

View File

@ -4,8 +4,6 @@
h1 session master mix
.dialog-inner
p.notice
| The master mix is the audio used for session recordings and live broadcasts. Changes to the master mix are global.&nbsp;
| The master mix does not include voice chat or the metronome. Any user in the session may use the volume and pan controls&nbsp;
| below to make adjustments to the master mix.
| The master mix is the audio mix used for both recordings and live broadcasts of session audio. Changes to the master mix are global, so there is only one master mix for the session. The master mix does not include controls for the metronome because the metronome is not recorded or broadcast. Any user in the session may use the volume and pan controls below to make adjustments to the master mix for everyone in the session.
= react_component 'SessionMasterMix', {}
a.button-orange.close-button layout-action="close" CLOSE

View File

@ -25,6 +25,9 @@ describe "Find Session", :js => true, :type => :feature, :capybara_feature => tr
RsvpSlot.delete_all
Invitation.delete_all
MusicSession.delete_all
Score.delete_all
User.delete_all
Score.connection.execute('delete from current_network_scores').check
end
describe "basic" do
@ -57,7 +60,7 @@ describe "Find Session", :js => true, :type => :feature, :capybara_feature => tr
it "find one active session" do
find('#btn-refresh').trigger(:click)
page.should have_no_selector('.paginate-wait')
find('.paginate-wait')
find('#sessions-active .found-session', count: 1)
end

View File

@ -1,7 +1,7 @@
require 'spec_helper'
require 'google_client'
describe "OAuth", :slow=>true, :js=>true, :type=>:feature, :capybara_feature=>true do
describe "OAuth", :slow=>true, :js=>true, :type=>:feature, :capybara_feature=>true, intermittent: true do
subject { page }
@ -40,7 +40,7 @@ describe "OAuth", :slow=>true, :js=>true, :type=>:feature, :capybara_feature=>tr
end
it "client should authorize a google user" do
authorize_google_user(@youtube_client, @user, "stinkyblueberryjam")
authorize_google_user(@youtube_client, @user, "filthyblueberryjam")
save_screenshot("working.png")
@user.reload
@user.user_authorizations.count.should eq(1)

View File

@ -102,7 +102,7 @@ describe "Reconnect", :js => true, :type => :feature, :capybara_feature => true
end
end
it "websocket goes down on session page" do
it "websocket goes down on session page", intermittent: true do
create_session(creator: user1)

View File

@ -20,7 +20,7 @@ describe "Session Recordings", :js => true, :type => :feature, :capybara_feature
end
# creates a recording, and stops it, and confirms the 'Finished Recording' dialog shows for both
it "creator start/stop" do
it "creator start/stop", intermittent: true do
start_recording_with(creator, [joiner1])
in_client(creator) { stop_recording }
check_recording_finished_for([creator, joiner1])

View File

@ -68,7 +68,9 @@ describe "Session Detail", :js => true, :type => :feature, :capybara_feature =>
should_not have_selector('td', text: searcher.name)
end
it "shows latency information correctly" do
it "shows latency information correctly", intermittent: true do
# intermittent: this fails a good amount on all environments
# this will try to show all 6 latency badges. unknown, good, fair, poor, unacceptable, and me
session_creator = requested_rsvp_slot.music_session.creator
session_creator.last_jam_locidispid = dallas_geoip[:locidispid]

View File

@ -2,7 +2,7 @@ require 'spec_helper'
require 'google_client'
require 'rest_client'
describe "YouTube", :slow=>true, :js=>true, :type => :feature, :capybara_feature => true do
describe "YouTube", :slow=>true, :js=>true, :type => :feature, :capybara_feature => true, intermittent: true do
subject { page }
# Authenticate with a test google account. This should create
@ -15,7 +15,7 @@ describe "YouTube", :slow=>true, :js=>true, :type => :feature, :capybara_feature
Capybara.run_server = false
@user=FactoryGirl.create(:user, :email => "jamkazamtest@gmail.com")
@youtube_client = GoogleClient.new()
authorize_google_user(@youtube_client, @user, "stinkyblueberryjam")
authorize_google_user(@youtube_client, @user, "filthyblueberryjam")
google_auth = UserAuthorization.google_auth(@user).first # Consider returning this from above now that it is reliable
end

View File

@ -54,6 +54,8 @@ RecordedTrack.observers.disable :all # only a few tests want this observer activ
require "test/unit"
Test::Unit::AutoRunner.need_auto_run = false
IS_BUILD_SERVER = !ENV['BUILD_SERVER'].nil?
# a way to kill tests if they aren't running. capybara is hanging intermittently, I think
tests_started = false
@ -174,6 +176,7 @@ bputs "before register capybara"
# by default, do not run tests marked as 'slow'
config.filter_run_excluding slow: true unless ENV['RUN_SLOW_TESTS'] == "1" || ENV['SLOW'] == "1" || ENV['ALL_TESTS'] == "1"
config.filter_run_excluding aws: true unless ENV['RUN_AWS_TESTS'] == "1" || ENV['AWS'] == "1" || ENV['ALL_TESTS'] == "1"
config.filter_run_excluding intermittent: true if IS_BUILD_SERVER
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
@ -192,7 +195,7 @@ bputs "before register capybara"
config.include Requests::FeatureHelpers, type: :feature
# Use the specified formatter
config.formatter = :documentation
#config.formatter = :documentation
config.before(:suite) do
tests_started = true

View File

@ -289,7 +289,7 @@ def verify_find_session_score(score, parent_selector, current_user, target_user)
end
find('#btn-refresh').trigger(:click)
page.should have_no_selector('.paginate-wait')
find('.paginate-wait')
page.assert_selector("div#{parent_selector} .found-session", count: 1)
hoverable = find(".latency-value#{expected[:latency_badge_selector]}[data-user-id='#{target_user.id}']", text: expected[:latency_badge_text])

View File

@ -103,6 +103,7 @@ def authorize_google_user(youtube_client, user, google_password)
# Wait for submit to enable and then click it:
sleep(5)
save_screenshot("about_to_submit.png")
find('#submit_approve_access').trigger(:click)
sleep(5)