Bugfix: Use server timestamp to set agent_last_seen_at (#1114)
This commit is contained in:
@@ -44,9 +44,8 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro
|
|||||||
end
|
end
|
||||||
|
|
||||||
def update_last_seen
|
def update_last_seen
|
||||||
@conversation.agent_last_seen_at = parsed_last_seen_at
|
@conversation.agent_last_seen_at = DateTime.now.utc
|
||||||
@conversation.save!
|
@conversation.save!
|
||||||
head :ok
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -56,10 +55,6 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro
|
|||||||
Rails.configuration.dispatcher.dispatch(event, Time.zone.now, conversation: @conversation, user: user)
|
Rails.configuration.dispatcher.dispatch(event, Time.zone.now, conversation: @conversation, user: user)
|
||||||
end
|
end
|
||||||
|
|
||||||
def parsed_last_seen_at
|
|
||||||
DateTime.strptime(params[:agent_last_seen_at].to_s, '%s')
|
|
||||||
end
|
|
||||||
|
|
||||||
def conversation
|
def conversation
|
||||||
@conversation ||= Current.account.conversations.find_by(display_id: params[:id])
|
@conversation ||= Current.account.conversations.find_by(display_id: params[:id])
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -29,10 +29,8 @@ class ConversationApi extends ApiClient {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
markMessageRead({ id, lastSeen }) {
|
markMessageRead({ id }) {
|
||||||
return axios.post(`${this.url}/${id}/update_last_seen`, {
|
return axios.post(`${this.url}/${id}/update_last_seen`);
|
||||||
agent_last_seen_at: lastSeen,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleTyping({ conversationId, status }) {
|
toggleTyping({ conversationId, status }) {
|
||||||
|
|||||||
@@ -218,12 +218,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
makeMessagesRead() {
|
makeMessagesRead() {
|
||||||
if (this.getUnreadCount !== 0 && this.getMessages !== undefined) {
|
this.$store.dispatch('markMessagesRead', { id: this.currentChat.id });
|
||||||
this.$store.dispatch('markMessagesRead', {
|
|
||||||
id: this.currentChat.id,
|
|
||||||
lastSeen: this.getMessages.messages.last().created_at,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -106,6 +106,9 @@ export default {
|
|||||||
this.isEditing = false;
|
this.isEditing = false;
|
||||||
},
|
},
|
||||||
async fetchLabels(conversationId) {
|
async fetchLabels(conversationId) {
|
||||||
|
if (!conversationId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.$store.dispatch('conversationLabels/get', conversationId);
|
this.$store.dispatch('conversationLabels/get', conversationId);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -170,11 +170,18 @@ const actions = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
markMessagesRead: async ({ commit }, data) => {
|
markMessagesRead: async ({ commit }, data) => {
|
||||||
setTimeout(() => {
|
|
||||||
commit(types.default.MARK_MESSAGE_READ, data);
|
|
||||||
}, 4000);
|
|
||||||
try {
|
try {
|
||||||
await ConversationApi.markMessageRead(data);
|
const {
|
||||||
|
data: { id, agent_last_seen_at: lastSeen },
|
||||||
|
} = await ConversationApi.markMessageRead(data);
|
||||||
|
setTimeout(
|
||||||
|
() =>
|
||||||
|
commit(types.default.MARK_MESSAGE_READ, {
|
||||||
|
id,
|
||||||
|
lastSeen,
|
||||||
|
}),
|
||||||
|
4000
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Handle error
|
// Handle error
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,7 +134,9 @@ export const mutations = {
|
|||||||
|
|
||||||
[types.default.MARK_MESSAGE_READ](_state, { id, lastSeen }) {
|
[types.default.MARK_MESSAGE_READ](_state, { id, lastSeen }) {
|
||||||
const [chat] = _state.allConversations.filter(c => c.id === id);
|
const [chat] = _state.allConversations.filter(c => c.id === id);
|
||||||
chat.agent_last_seen_at = lastSeen;
|
if (chat) {
|
||||||
|
chat.agent_last_seen_at = lastSeen;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
[types.default.CHANGE_CHAT_STATUS_FILTER](_state, data) {
|
[types.default.CHANGE_CHAT_STATUS_FILTER](_state, data) {
|
||||||
|
|||||||
@@ -153,4 +153,28 @@ describe('#actions', () => {
|
|||||||
expect(commit.mock.calls).toEqual([[types.default.ADD_MESSAGE, message]]);
|
expect(commit.mock.calls).toEqual([[types.default.ADD_MESSAGE, message]]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#markMessagesRead', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sends correct mutations if api is successful', async () => {
|
||||||
|
const lastSeen = new Date().getTime() / 1000;
|
||||||
|
axios.post.mockResolvedValue({
|
||||||
|
data: { id: 1, agent_last_seen_at: lastSeen },
|
||||||
|
});
|
||||||
|
await actions.markMessagesRead({ commit }, { id: 1 });
|
||||||
|
jest.runAllTimers();
|
||||||
|
expect(commit).toHaveBeenCalledTimes(1);
|
||||||
|
expect(commit.mock.calls).toEqual([
|
||||||
|
[types.default.MARK_MESSAGE_READ, { id: 1, lastSeen }],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
it('sends correct mutations if api is unsuccessful', async () => {
|
||||||
|
axios.post.mockRejectedValue({ message: 'Incorrect header' });
|
||||||
|
await actions.markMessagesRead({ commit }, { id: 1 });
|
||||||
|
expect(commit.mock.calls).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,6 +20,13 @@ describe('#mutations', () => {
|
|||||||
{ id: 1, agent_last_seen_at: lastSeen },
|
{ id: 1, agent_last_seen_at: lastSeen },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('doesnot send any mutation if chat doesnot exist', () => {
|
||||||
|
const state = { allConversations: [] };
|
||||||
|
const lastSeen = new Date().getTime() / 1000;
|
||||||
|
mutations[types.MARK_MESSAGE_READ](state, { id: 1, lastSeen });
|
||||||
|
expect(state.allConversations).toEqual([]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#CLEAR_CURRENT_CHAT_WINDOW', () => {
|
describe('#CLEAR_CURRENT_CHAT_WINDOW', () => {
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
json.partial! 'api/v1/conversations/partials/conversation.json.jbuilder', conversation: @conversation
|
||||||
7
db/migrate/20200802170002_reset_agent_last_seen_at.rb
Normal file
7
db/migrate/20200802170002_reset_agent_last_seen_at.rb
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
class ResetAgentLastSeenAt < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
# rubocop:disable Rails/SkipsModelValidations
|
||||||
|
::Conversation.where('agent_last_seen_at > ?', DateTime.now.utc).update_all(agent_last_seen_at: DateTime.now.utc)
|
||||||
|
# rubocop:enable Rails/SkipsModelValidations
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2020_07_19_171437) do
|
ActiveRecord::Schema.define(version: 2020_08_02_170002) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "pg_stat_statements"
|
enable_extension "pg_stat_statements"
|
||||||
|
|||||||
@@ -177,15 +177,12 @@ RSpec.describe 'Conversations API', type: :request do
|
|||||||
let(:agent) { create(:user, account: account, role: :agent) }
|
let(:agent) { create(:user, account: account, role: :agent) }
|
||||||
|
|
||||||
it 'updates last seen' do
|
it 'updates last seen' do
|
||||||
params = { agent_last_seen_at: '-1' }
|
|
||||||
|
|
||||||
post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/update_last_seen",
|
post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/update_last_seen",
|
||||||
headers: agent.create_new_auth_token,
|
headers: agent.create_new_auth_token,
|
||||||
params: params,
|
|
||||||
as: :json
|
as: :json
|
||||||
|
|
||||||
expect(response).to have_http_status(:success)
|
expect(response).to have_http_status(:success)
|
||||||
expect(conversation.reload.agent_last_seen_at).to eq(DateTime.strptime(params[:agent_last_seen_at].to_s, '%s'))
|
expect(conversation.reload.agent_last_seen_at).not_to eq nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user