Bugfix: Use server timestamp to set agent_last_seen_at (#1114)

This commit is contained in:
Pranav Raj S 2020-08-03 13:40:20 +05:30 committed by GitHub
parent 941272cccd
commit 3b23aa7913
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 62 additions and 26 deletions

View file

@ -44,9 +44,8 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro
end
def update_last_seen
@conversation.agent_last_seen_at = parsed_last_seen_at
@conversation.agent_last_seen_at = DateTime.now.utc
@conversation.save!
head :ok
end
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)
end
def parsed_last_seen_at
DateTime.strptime(params[:agent_last_seen_at].to_s, '%s')
end
def conversation
@conversation ||= Current.account.conversations.find_by(display_id: params[:id])
end

View file

@ -29,10 +29,8 @@ class ConversationApi extends ApiClient {
);
}
markMessageRead({ id, lastSeen }) {
return axios.post(`${this.url}/${id}/update_last_seen`, {
agent_last_seen_at: lastSeen,
});
markMessageRead({ id }) {
return axios.post(`${this.url}/${id}/update_last_seen`);
}
toggleTyping({ conversationId, status }) {

View file

@ -218,12 +218,7 @@ export default {
},
makeMessagesRead() {
if (this.getUnreadCount !== 0 && this.getMessages !== undefined) {
this.$store.dispatch('markMessagesRead', {
id: this.currentChat.id,
lastSeen: this.getMessages.messages.last().created_at,
});
}
this.$store.dispatch('markMessagesRead', { id: this.currentChat.id });
},
},
};

View file

@ -106,6 +106,9 @@ export default {
this.isEditing = false;
},
async fetchLabels(conversationId) {
if (!conversationId) {
return;
}
this.$store.dispatch('conversationLabels/get', conversationId);
},
},

View file

@ -170,11 +170,18 @@ const actions = {
},
markMessagesRead: async ({ commit }, data) => {
setTimeout(() => {
commit(types.default.MARK_MESSAGE_READ, data);
}, 4000);
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) {
// Handle error
}

View file

@ -134,7 +134,9 @@ export const mutations = {
[types.default.MARK_MESSAGE_READ](_state, { id, lastSeen }) {
const [chat] = _state.allConversations.filter(c => c.id === id);
if (chat) {
chat.agent_last_seen_at = lastSeen;
}
},
[types.default.CHANGE_CHAT_STATUS_FILTER](_state, data) {

View file

@ -153,4 +153,28 @@ describe('#actions', () => {
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([]);
});
});
});

View file

@ -20,6 +20,13 @@ describe('#mutations', () => {
{ 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', () => {

View file

@ -0,0 +1 @@
json.partial! 'api/v1/conversations/partials/conversation.json.jbuilder', conversation: @conversation

View 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

View file

@ -10,7 +10,7 @@
#
# 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
enable_extension "pg_stat_statements"

View file

@ -177,15 +177,12 @@ RSpec.describe 'Conversations API', type: :request do
let(:agent) { create(:user, account: account, role: :agent) }
it 'updates last seen' do
params = { agent_last_seen_at: '-1' }
post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/update_last_seen",
headers: agent.create_new_auth_token,
params: params,
as: :json
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