diff --git a/src/analytics/analytics.js b/src/analytics/analytics.js index 54a8630..d33499e 100755 --- a/src/analytics/analytics.js +++ b/src/analytics/analytics.js @@ -5,6 +5,19 @@ import LoggingService from '../services/LoggingService'; const eventLogApiBaseUrl = `${configuration.LMS_BASE_URL}/event`; + +// Uses a JSON as a source of key value pairs for x-www-form-urlencoded output. +// Note should be handled by axios, but is not built in. +// - see https://github.com/axios/axios/issues/97 +function xWwwFormUrlEncoded(json) { + const data = []; + Object.keys(json).forEach((key) => { + data.push(`${encodeURIComponent(key)}=${encodeURIComponent(json[key])}`); + }); + return data.join('&'); +} + + // Sends events to Segment and downstream function handleTrackEvents(eventName, properties) { // Simply forward track events to Segment @@ -21,7 +34,15 @@ function logEvent(eventType, eventData) { event: JSON.stringify(snakeEventData), page: window.location.href, }; - return apiClient.post(eventLogApiBaseUrl, serverData) + return apiClient.post( + eventLogApiBaseUrl, + xWwwFormUrlEncoded(serverData), + { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + }, + ) .catch((error) => { LoggingService.logAPIErrorResponse(error); }); diff --git a/src/analytics/analytics.test.js b/src/analytics/analytics.test.js index f22f641..f514070 100644 --- a/src/analytics/analytics.test.js +++ b/src/analytics/analytics.test.js @@ -25,16 +25,15 @@ describe('analytics logEvent', () => { it('posts expected data when successful', () => { jest.spyOn(apiClient, 'post').mockResolvedValue(undefined); - expect.assertions(3); + expect.assertions(4); return logEvent(eventType, eventData) .then(() => { expect(apiClient.post.mock.calls.length).toEqual(1); expect(apiClient.post.mock.calls[0][0]).toEqual(`${configuration.LMS_BASE_URL}/event`); - expect(apiClient.post.mock.calls[0][1]).toEqual({ - event_type: 'test.event', - event: '{"test_shallow":"test-shallow","test_object":{"test_deep":"test-deep"}}', - page: window.location.href, - }); + const data = 'event_type=test.event&event=%7B%22test_shallow%22%3A%22test-shallow%22%2C%22test_object%22%3A%7B%22test_deep%22%3A%22test-deep%22%7D%7D&page=http%3A%2F%2Flocalhost%2F'; + expect(apiClient.post.mock.calls[0][1]).toEqual(data); + const config = apiClient.post.mock.calls[0][2]; + expect(config.headers['Content-Type']).toEqual('application/x-www-form-urlencoded'); }); });