Skip to content

Commit

Permalink
Merge pull request #105 from wireapp/dev
Browse files Browse the repository at this point in the history
staging bump 2016-08-22
  • Loading branch information
Gregor Herdmann authored Aug 22, 2016
2 parents 310316d + 3a423ed commit fa8b457
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 29 deletions.
18 changes: 13 additions & 5 deletions app/script/audio/AudioRepository.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -165,16 +165,24 @@ class z.audio.AudioRepository
@return [Promise] Resolves with the HTMLAudioElement
###
_play: (audio_id, audio_element, play_in_loop = false) ->
return new Promise (resolve, reject) ->
if not audio_id or not audio_element
return Promise.reject new z.audio.AudioError 'Missing AudioElement or ID', z.audio.AudioError::TYPE.NOT_FOUND

return new Promise (resolve, reject) =>
if audio_element.paused
audio_element.loop = play_in_loop
audio_element.currentTime = 0 if audio_element.currentTime isnt 0
audio_element.play()
.then =>
play_promise = audio_element.play()

_play_success = =>
@currently_looping[audio_id] = audio_id if play_in_loop
resolve audio_element
.catch (error) ->
reject new z.audio.AudioError error.message, z.audio.AudioError::TYPE.FAILED_TO_PLAY

if play_promise
play_promise.then(_play_success).catch (error) ->
reject new z.audio.AudioError error.message, z.audio.AudioError::TYPE.FAILED_TO_PLAY
else
_play_success()
else
reject new z.audio.AudioError 'Sound is already playing', z.audio.AudioError::TYPE.ALREADY_PLAYING

Expand Down
2 changes: 1 addition & 1 deletion app/script/components/deviceRemove.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ ko.components.register 'device-remove',
<form class="device-remove-form" data-bind="submit: click_on_submit, attr: {'data-uie-value': model}" data-ui-name="device-remove-form">
<input class="device-remove-input"
type="password"
data-bind="textInput: password, l10n_placeholder: z.string.auth_placeholder_password_put, css: {'device-remove-input-error': device_remove_error}"
data-bind="hasfocus: true, textInput: password, l10n_placeholder: z.string.auth_placeholder_password_put, css: {'device-remove-input-error': device_remove_error}"
data-uie-name="remove-device-password" />
<button class="device-remove-button-remove button button-medium button-fluid"
data-bind="attr: {'data-uie-value': model}, l10n_text: z.string.preferences_device_button_remove"
Expand Down
31 changes: 22 additions & 9 deletions app/script/conversation/ConversationRepository.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,9 @@ class z.conversation.ConversationRepository
###
delete_message_everyone: (conversation_et, message_et) =>
Promise.resolve()
.then ->
if not message_et.user().is_me
throw new Error 'Cannot delete other users message'
.then ->
generic_message = new z.proto.GenericMessage z.util.create_random_uuid()
generic_message.set 'deleted', new z.proto.MessageDelete message_et.id
Expand Down Expand Up @@ -1333,27 +1336,37 @@ class z.conversation.ConversationRepository
# Event callbacks
###############################################################################

message_hidden: (event_json) =>
Promise.resolve()
.then =>
if event_json.from isnt @user_repository.self().id
throw new Error 'Sender is not self user'
return @find_conversation_by_id event_json.data.conversation_id
.then (conversation_et) =>
return @_delete_message conversation_et, event_json.data.message_id
.catch (error) =>
@logger.log "Failed to delete message for conversation '#{conversation_et.id}'", error
throw error

message_deleted: (event_json) =>
conversation_et = undefined
message_to_delete_id = undefined

Promise.resolve()
.then =>
message_to_delete_id = event_json.data.message_id
conversation_id = event_json.data.conversation_id or event_json.conversation
conversation_et = @find_conversation_by_id conversation_id
conversation_et = @find_conversation_by_id event_json.conversation
.then =>
@get_message_from_db conversation_et, message_to_delete_id
@get_message_from_db conversation_et, event_json.data.message_id
.then (message_to_delete_et) =>
if @user_repository.self().id isnt event_json.from
if event_json.from isnt message_to_delete_et.from
throw new Error 'Sender can only delete own messages'
if event_json.from isnt @user_repository.self().id
return @_add_delete_message conversation_et.id, event_json.id, event_json.time, message_to_delete_et
.then =>
return @_delete_message conversation_et, message_to_delete_id
return @_delete_message conversation_et, event_json.data.message_id
.catch (error) =>
@logger.log "Failed to delete message for conversation '#{conversation_et.id}'", error
throw error


###
Add delete message to conversation
@param conversation_id [String]
Expand Down Expand Up @@ -1667,7 +1680,7 @@ class z.conversation.ConversationRepository
when z.event.Backend.CONVERSATION.MESSAGE_DELETE
@message_deleted event
when z.event.Backend.CONVERSATION.MESSAGE_HIDDEN
@message_deleted event
@message_hidden event
else
@add_event conversation_et, event

Expand Down
1 change: 0 additions & 1 deletion app/script/cryptography/CryptographyMapper.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ class z.cryptography.CryptographyMapper
_map_deleted: (deleted) ->
return {
data:
conversation_id: deleted.conversation_id
message_id: deleted.message_id
type: z.event.Backend.CONVERSATION.MESSAGE_DELETE
}
Expand Down
2 changes: 2 additions & 0 deletions app/script/main/app.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -443,10 +443,12 @@ class z.main.App

# Disable debugging on any environment.
disable_debugging: ->
z.config.LOGGER.OPTIONS.domains['app.wire.com'] = -> 0
amplify.publish z.event.WebApp.PROPERTIES.CHANGE.DEBUG, false

# Enable debugging on any environment.
enable_debugging: ->
z.config.LOGGER.OPTIONS.domains['app.wire.com'] = -> 300
amplify.publish z.event.WebApp.PROPERTIES.CHANGE.DEBUG, true

# Report call telemetry to Raygun for analysis.
Expand Down
2 changes: 1 addition & 1 deletion app/script/view_model/MessageListViewModel.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ class z.ViewModel.MessageListViewModel
if message_et.is_deletable()
entries.push {label: z.string.conversation_context_menu_delete, action: 'delete'}

if message_et.user().is_me
if message_et.user().is_me and not @conversation().removed_from_conversation()
entries.push {label: z.string.conversation_context_menu_delete_everyone, action: 'delete-everyone'}

return entries
Expand Down
9 changes: 5 additions & 4 deletions app/script/view_model/bindings/CommonBindings.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -274,14 +274,15 @@ ko.bindingHandlers.relative_timestamp = do ->
ko.bindingHandlers.hide_controls =
init: (element, valueAccessor) ->
timeout = valueAccessor()
timer = undefined
hide_timeout = undefined

element.onmouseenter = -> element.classList.remove 'hide-controls'
element.onmouseleave = -> element.classList.add 'hide-controls'
element.onmouseleave = -> element.classList.add 'hide-controls' if document.hasFocus()
element.onmousemove = ->
window.clearTimeout timer if timer
window.clearTimeout hide_timeout if hide_timeout

element.classList.remove 'hide-controls'

timer = window.setTimeout ->
hide_timeout = window.setTimeout ->
element.classList.add 'hide-controls'
, timeout
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"grunt-todo": "0.5.0",
"jasmine-ajax": "3.2.0",
"jasmine-core": "2.4.1",
"karma": "1.2.0",
"karma": "1.1.2",
"karma-chrome-launcher": "1.0.1",
"karma-coverage": "1.1.1",
"karma-jasmine": "1.0.2",
Expand Down
22 changes: 19 additions & 3 deletions test/unit_tests/audio/AudioRepositorySpec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ describe 'z.audio.AudioRepository', ->
expect(error.type).toBe z.audio.AudioError::TYPE.NOT_FOUND
done()

xdescribe '_play', ->
describe '_play', ->
beforeEach ->
audio_repository.audio_elements[z.audio.AudioType.OUTGOING_CALL] = new Audio "/audio/#{z.audio.AudioType.OUTGOING_CALL}.mp3"

afterEach ->
audio_repository.audio_elements[z.audio.AudioType.OUTGOING_CALL].stop()
audio_repository.audio_elements[z.audio.AudioType.OUTGOING_CALL].pause()

it 'plays an available sound', (done) ->
audio_repository._play z.audio.AudioType.OUTGOING_CALL, audio_repository.audio_elements[z.audio.AudioType.OUTGOING_CALL], false
Expand All @@ -87,10 +87,26 @@ describe 'z.audio.AudioRepository', ->
it 'does not play a sound twice concurrently', (done) ->
audio_repository.audio_elements[z.audio.AudioType.OUTGOING_CALL].play()
.then ->
audio_repository._play z.audio.AudioType.OUTGOING_CALL
audio_repository._play z.audio.AudioType.OUTGOING_CALL, audio_repository.audio_elements[z.audio.AudioType.OUTGOING_CALL]
.then done.fail
.catch (error) ->
expect(error).toEqual jasmine.any z.audio.AudioError
expect(error.type).toBe z.audio.AudioError::TYPE.ALREADY_PLAYING
done()
.catch done.fail

it 'handles a missing audio id sound', (done) ->
audio_repository._play undefined, audio_repository.audio_elements[z.audio.AudioType.OUTGOING_CALL]
.catch (error) ->
expect(error).toEqual jasmine.any z.audio.AudioError
expect(error.type).toBe z.audio.AudioError::TYPE.NOT_FOUND
done()
.catch done.fail

it 'handles a missing audio element', (done) ->
audio_repository._play z.audio.AudioType.OUTGOING_CALL, undefined
.catch (error) ->
expect(error).toEqual jasmine.any z.audio.AudioError
expect(error.type).toBe z.audio.AudioError::TYPE.NOT_FOUND
done()
.catch done.fail
100 changes: 96 additions & 4 deletions test/unit_tests/conversation/ConversationRepositorySpec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,91 @@ describe 'z.conversation.ConversationRepository', ->
result = conversation_repository.get_groups_by_name 'Removed'
expect(result.length).toBe 0

describe 'delete_message_everyone', ->

conversation_et = null

beforeEach ->
conversation_et = _generate_conversation z.conversation.ConversationType.REGULAR

spyOn(conversation_repository, '_send_encrypted_value').and.returnValue Promise.resolve()

it 'does not delete other users messages', (done) ->
user_et = new z.entity.User()
user_et.is_me = false
message_to_delete_et = new z.entity.Message()
message_to_delete_et.id = z.util.create_random_uuid()
message_to_delete_et.user user_et
conversation_et.add_message message_to_delete_et

conversation_repository.delete_message_everyone conversation_et, message_to_delete_et
.then done.fail
.catch done

it 'sends delete and deletes message for own messages', (done) ->
user_et = new z.entity.User()
user_et.is_me = true
message_to_delete_et = new z.entity.Message()
message_to_delete_et.id = z.util.create_random_uuid()
message_to_delete_et.user user_et
conversation_et.add_message message_to_delete_et

expect(conversation_et.get_message_by_id(message_to_delete_et.id)).toBeDefined()
conversation_repository.delete_message_everyone conversation_et, message_to_delete_et
.then ->
expect(conversation_et.get_message_by_id(message_to_delete_et.id)).not.toBeDefined()
done()
.catch done.fail

describe 'message_hidden', ->

conversation_et = null
message_to_hide_et = null

beforeEach ->
conversation_et = _generate_conversation z.conversation.ConversationType.REGULAR
conversation_repository.save_conversation conversation_et

message_to_hide_et = new z.entity.PingMessage()
message_to_hide_et.id = z.util.create_random_uuid()
conversation_et.add_message message_to_hide_et

it 'does not hide message if sender is not self user', (done) ->
event =
conversation: conversation_et.id
id: z.util.create_random_uuid()
data:
message_id: message_to_hide_et.id
conversation_id: conversation_et.id
from: z.util.create_random_uuid()
time: new Date().toISOString()
type: z.event.Backend.CONVERSATION.MESSAGE_HIDDEN

expect(conversation_et.get_message_by_id(message_to_hide_et.id)).toBeDefined()
conversation_repository.message_hidden event
.then done.fail
.catch ->
expect(conversation_et.get_message_by_id(message_to_hide_et.id)).toBeDefined()
done()

it 'hides message if sender is self user', (done) ->
event =
conversation: conversation_et.id
id: z.util.create_random_uuid()
data:
message_id: message_to_hide_et.id
conversation_id: conversation_et.id
from: user_repository.self().id
time: new Date().toISOString()
type: z.event.Backend.CONVERSATION.MESSAGE_HIDDEN

expect(conversation_et.get_message_by_id(message_to_hide_et.id)).toBeDefined()
conversation_repository.message_hidden event
.then ->
expect(conversation_et.get_message_by_id(message_to_hide_et.id)).not.toBeDefined()
done()
.catch done.fail

describe 'message_deleted', ->

conversation_et = null
Expand All @@ -299,10 +384,10 @@ describe 'z.conversation.ConversationRepository', ->

message_to_delete_et = new z.entity.PingMessage()
message_to_delete_et.id = z.util.create_random_uuid()
message_to_delete_et.from = user_repository.self().id
conversation_et.add_message message_to_delete_et

spyOn(conversation_repository, 'get_message_from_db').and.returnValue Promise.resolve message_to_delete_et
spyOn conversation_repository, '_delete_message'
spyOn conversation_repository, '_add_delete_message'

it 'deletes message if user is self', (done) ->
Expand All @@ -313,26 +398,33 @@ describe 'z.conversation.ConversationRepository', ->
message_id: message_to_delete_et.id
from: user_repository.self().id
time: new Date().toISOString()
type: z.event.Backend.CONVERSATION.MESSAGE_DELETE

expect(conversation_et.get_message_by_id(message_to_delete_et.id)).toBeDefined()
conversation_repository.message_deleted event
.then ->
expect(conversation_repository._delete_message).toHaveBeenCalledWith conversation_et, message_to_delete_et.id
expect(conversation_et.get_message_by_id(message_to_delete_et.id)).not.toBeDefined()
expect(conversation_repository._add_delete_message).not.toHaveBeenCalled()
done()
.catch done.fail

it 'deletes message and add delete message if user is not self', (done) ->
other_user_id = z.util.create_random_uuid()
message_to_delete_et.from = other_user_id

event =
conversation: conversation_et.id
id: z.util.create_random_uuid()
data:
message_id: message_to_delete_et.id
from: z.util.create_random_uuid()
from: other_user_id
time: new Date().toISOString()
type: z.event.Backend.CONVERSATION.MESSAGE_DELETE

expect(conversation_et.get_message_by_id(message_to_delete_et.id)).toBeDefined()
conversation_repository.message_deleted event
.then ->
expect(conversation_repository._delete_message).toHaveBeenCalledWith conversation_et, message_to_delete_et.id
expect(conversation_et.get_message_by_id(message_to_delete_et.id)).not.toBeDefined()
expect(conversation_repository._add_delete_message).toHaveBeenCalled()
done()
.catch done.fail
Expand Down

0 comments on commit fa8b457

Please sign in to comment.