From 63d3581e66acc21b79130c5f13bde88a74d136ac Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 12 Mar 2018 09:57:22 +0000 Subject: [PATCH] fixed note polling not sending updated last fetched at date added spec for polling --- .../notes/services/notes_service.js | 5 +- .../javascripts/notes/stores/actions.js | 6 +- spec/javascripts/notes/mock_data.js | 2 +- spec/javascripts/notes/stores/actions_spec.js | 65 +++++++++++++++++++ 4 files changed, 71 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/notes/services/notes_service.js b/app/assets/javascripts/notes/services/notes_service.js index bb31be583c7..b4c19a9ec22 100644 --- a/app/assets/javascripts/notes/services/notes_service.js +++ b/app/assets/javascripts/notes/services/notes_service.js @@ -27,10 +27,11 @@ export default { return Vue.http[method](endpoint); }, poll(data = {}) { - const { endpoint, lastFetchedAt } = data; + const endpoint = data.notesData.notesPath; + const lastFetchedAt = data.lastFetchedAt; const options = { headers: { - 'X-Last-Fetched-At': `${lastFetchedAt}`, + 'X-Last-Fetched-At': lastFetchedAt ? `${lastFetchedAt}` : undefined, }, }; diff --git a/app/assets/javascripts/notes/stores/actions.js b/app/assets/javascripts/notes/stores/actions.js index 3eaae0bc683..fc7faf05c5f 100644 --- a/app/assets/javascripts/notes/stores/actions.js +++ b/app/assets/javascripts/notes/stores/actions.js @@ -203,12 +203,10 @@ const pollSuccessCallBack = (resp, commit, state, getters) => { }; export const poll = ({ commit, state, getters }) => { - const requestData = { endpoint: state.notesData.notesPath, lastFetchedAt: state.lastFetchedAt }; - eTagPoll = new Poll({ resource: service, method: 'poll', - data: requestData, + data: state, successCallback: resp => resp.json() .then(data => pollSuccessCallBack(data, commit, state, getters)), errorCallback: () => Flash('Something went wrong while fetching latest comments.'), @@ -217,7 +215,7 @@ export const poll = ({ commit, state, getters }) => { if (!Visibility.hidden()) { eTagPoll.makeRequest(); } else { - service.poll(requestData); + service.poll(state); } Visibility.change(() => { diff --git a/spec/javascripts/notes/mock_data.js b/spec/javascripts/notes/mock_data.js index bf60cb12f52..5be13ed0dfe 100644 --- a/spec/javascripts/notes/mock_data.js +++ b/spec/javascripts/notes/mock_data.js @@ -1,7 +1,7 @@ /* eslint-disable */ export const notesDataMock = { discussionsPath: '/gitlab-org/gitlab-ce/issues/26/discussions.json', - lastFetchedAt: '1501862675', + lastFetchedAt: 1501862675, markdownDocsPath: '/help/user/markdown', newSessionPath: '/users/sign_in?redirect_to_referer=yes', notesPath: '/gitlab-org/gitlab-ce/noteable/issue/98/notes', diff --git a/spec/javascripts/notes/stores/actions_spec.js b/spec/javascripts/notes/stores/actions_spec.js index ab80ed7bbfb..b838cc36fb3 100644 --- a/spec/javascripts/notes/stores/actions_spec.js +++ b/spec/javascripts/notes/stores/actions_spec.js @@ -1,5 +1,6 @@ import Vue from 'vue'; import _ from 'underscore'; +import { headersInterceptor } from 'spec/helpers/vue_resource_helper'; import * as actions from '~/notes/stores/actions'; import store from '~/notes/stores'; import testAction from '../../helpers/vuex_action_helper'; @@ -129,4 +130,68 @@ describe('Actions Notes Store', () => { ], done); }); }); + + describe('poll', () => { + beforeEach((done) => { + jasmine.clock().install(); + + spyOn(Vue.http, 'get').and.callThrough(); + + store.dispatch('setNotesData', notesDataMock) + .then(done) + .catch(done.fail); + }); + + afterEach(() => { + jasmine.clock().uninstall(); + }); + + it('calls service with last fetched state', (done) => { + const interceptor = (request, next) => { + next(request.respondWith(JSON.stringify({ + notes: [], + last_fetched_at: '123456', + }), { + status: 200, + headers: { + 'poll-interval': '1000', + }, + })); + }; + + Vue.http.interceptors.push(interceptor); + Vue.http.interceptors.push(headersInterceptor); + + store.dispatch('poll') + .then(() => new Promise(resolve => requestAnimationFrame(resolve))) + .then(() => { + expect(Vue.http.get).toHaveBeenCalledWith(jasmine.anything(), { + url: jasmine.anything(), + method: 'get', + headers: { + 'X-Last-Fetched-At': undefined, + }, + }); + expect(store.state.lastFetchedAt).toBe('123456'); + + jasmine.clock().tick(1500); + }) + .then(() => new Promise((resolve) => { + requestAnimationFrame(resolve); + })) + .then(() => { + expect(Vue.http.get.calls.count()).toBe(2); + expect(Vue.http.get.calls.mostRecent().args[1].headers).toEqual({ + 'X-Last-Fetched-At': '123456', + }); + }) + .then(() => store.dispatch('stopPolling')) + .then(() => { + Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor); + Vue.http.interceptors = _.without(Vue.http.interceptors, headersInterceptor); + }) + .then(done) + .catch(done.fail); + }); + }); });