From 86cd0f09d9bf9e94cefd4e018dc61eb63ff575d0 Mon Sep 17 00:00:00 2001 From: Mila Frerichs Date: Tue, 18 Aug 2015 16:29:05 +0200 Subject: [PATCH 01/13] Add first test for popular pages --- karma.conf.js | 1 + public/javascripts/content.js | 9 +++++++-- tests/contentSpec.js | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 tests/contentSpec.js diff --git a/karma.conf.js b/karma.conf.js index 8ae7e2f..c2be70d 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -5,6 +5,7 @@ module.exports = function(config) { files: [ 'public/javascripts/vendor/d3.v3.min.js', 'public/javascripts/traffic.js', + 'public/javascripts/content.js', 'tests/**/*Spec.js', 'tests/fixtures/**/*' ], diff --git a/public/javascripts/content.js b/public/javascripts/content.js index 4b14760..3e7497e 100644 --- a/public/javascripts/content.js +++ b/public/javascripts/content.js @@ -7,8 +7,13 @@ pages: [], el: false, - endpoint: function(){ - return "/realtime?ids=ga:"+matrix.settings.profileId+"&metrics=rt%3Apageviews&dimensions=rt%3ApageTitle,rt:pagePath&max-results=10&sort=-rt%3Apageviews" + endpoint: function(){ + return "/realtime?"+ + "ids=ga:"+matrix.settings.profileId+"&"+ + "metrics=rt:pageviews&"+ + "dimensions=rt:pageTitle,rt:pagePath&"+ + "max-results=10&"+ + "sort=-rt%3Apageviews" }, parseResponse: function(data){ var i, _i; diff --git a/tests/contentSpec.js b/tests/contentSpec.js new file mode 100644 index 0000000..a975e2f --- /dev/null +++ b/tests/contentSpec.js @@ -0,0 +1,32 @@ +describe('traffic', function() { + beforeEach(function() { + window.matrix.settings = { + profileId: '' + }; + subject = window.matrix.content; + sandbox = sinon.sandbox.create(); + server = sinon.fakeServer.create(); + }); + afterEach(function() { + sandbox.restore(); + server.restore(); + }); + it('has initial points', function() { + expect(subject.pages).to.eql([]); + }); + describe('#endpoint', function() { + it('returns the path to the servers realtime endpoint', function() { + expect(subject.endpoint()).to.eql('/realtime?ids=ga:&metrics=rt:pageviews&dimensions=rt:pageTitle,rt:pagePath&max-results=10&sort=-rt%3Apageviews'); + }); + context('with profileId', function() { + beforeEach(function() { + window.matrix.settings = { + profileId: 'Test' + }; + }); + it('returns correct profile Id in the endpoint path', function() { + expect(subject.endpoint()).to.eql('/realtime?ids=ga:Test&metrics=rt:pageviews&dimensions=rt:pageTitle,rt:pagePath&max-results=10&sort=-rt%3Apageviews'); + }); + }); + }); +}); From e2eaf48c0cc9198a388e42d8c2ca5aa446df409e Mon Sep 17 00:00:00 2001 From: Mila Frerichs Date: Wed, 19 Aug 2015 11:38:42 +0200 Subject: [PATCH 02/13] Add tests for init method --- tests/contentSpec.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/contentSpec.js b/tests/contentSpec.js index a975e2f..9b2705d 100644 --- a/tests/contentSpec.js +++ b/tests/contentSpec.js @@ -11,9 +11,24 @@ describe('traffic', function() { sandbox.restore(); server.restore(); }); - it('has initial points', function() { + it('empty pages', function() { expect(subject.pages).to.eql([]); }); + describe('#init', function() { + it("calls reload", function() { + mock = sandbox.mock(subject).expects("reload").once(); + subject.init(); + mock.verify(); + }); + it("calls reload with interval of 30 minute", function() { + clock = sinon.useFakeTimers(Date.now()); + mock = sandbox.mock(subject).expects("reload").twice(); + subject.init(); + clock.tick(1800000); + mock.verify(); + clock.restore(); + }); + }); describe('#endpoint', function() { it('returns the path to the servers realtime endpoint', function() { expect(subject.endpoint()).to.eql('/realtime?ids=ga:&metrics=rt:pageviews&dimensions=rt:pageTitle,rt:pagePath&max-results=10&sort=-rt%3Apageviews'); From b730a58301e833704a9cc1cf3cc50d90a18d2a52 Mon Sep 17 00:00:00 2001 From: Mila Frerichs Date: Wed, 19 Aug 2015 11:40:08 +0200 Subject: [PATCH 03/13] Add test for reload method --- tests/contentSpec.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/contentSpec.js b/tests/contentSpec.js index 9b2705d..5a44ee2 100644 --- a/tests/contentSpec.js +++ b/tests/contentSpec.js @@ -29,6 +29,25 @@ describe('traffic', function() { clock.restore(); }); }); + describe('#reload', function() { + it("calls endpoint", function() { + sandbox.stub(d3, "json"); + mock = sandbox.mock(subject).expects("endpoint").once(); + subject.reload(); + mock.verify(); + }); + context('json returned', function(){ + beforeEach(function() { + stub = sandbox.stub(d3, 'json'); + }); + it("calls parseResponse", function() { + mock = sandbox.mock(subject).expects("parseResponse").once(); + subject.reload(); + stub.callArgWith(1, {}, {}); + mock.verify(); + }); + }); + }); describe('#endpoint', function() { it('returns the path to the servers realtime endpoint', function() { expect(subject.endpoint()).to.eql('/realtime?ids=ga:&metrics=rt:pageviews&dimensions=rt:pageTitle,rt:pagePath&max-results=10&sort=-rt%3Apageviews'); From bdc6c968bc7b58c8bc81ee75913142323828c639 Mon Sep 17 00:00:00 2001 From: Mila Frerichs Date: Wed, 19 Aug 2015 11:46:00 +0200 Subject: [PATCH 04/13] Add first test for parseResponse method add error handling to parseResponse if d3.json failes, or if there are no results in the API reponse --- public/javascripts/content.js | 11 +++++------ tests/contentSpec.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/public/javascripts/content.js b/public/javascripts/content.js index 3e7497e..f55f50e 100644 --- a/public/javascripts/content.js +++ b/public/javascripts/content.js @@ -15,17 +15,16 @@ "max-results=10&"+ "sort=-rt%3Apageviews" }, - parseResponse: function(data){ + parseResponse: function(error, data){ var i, _i; - + if(error) { return -1; } + if(!data.hasOwnProperty("rows")) { return -1; } content.pages = []; for(i=0,_i=data.rows.length; i<_i; i++){ content.pages.push({ - title: data.rows[i][0],//.split(' — ').slice(0,-1).join(' - '), + title: data.rows[i][0], url: data.rows[i][1], - visits: data.rows[i][2] - //displayHits: root.matrix.numberWithCommas(data.rows[i].week2), - //percentageUp: root.matrix.numberWithCommas(Math.round(data.rows[i].percent_change)) + "%" + visits: parseInt(data.rows[i][2]) }); } diff --git a/tests/contentSpec.js b/tests/contentSpec.js index 5a44ee2..8fdbfbc 100644 --- a/tests/contentSpec.js +++ b/tests/contentSpec.js @@ -48,6 +48,34 @@ describe('traffic', function() { }); }); }); + describe('#parseResponse', function() { + context("error parsing json", function() { + it("does not display the results", function() { + mock = sandbox.mock(subject).expects("displayResults").never(); + subject.parseResponse({}, null); + mock.verify(); + }); + }); + context("no error parsing json", function() { + context("has data from GA", function() { + beforeEach(function() { + data = { rows: [["Titel 1","url 1","1"]] }; + subject.pages = []; + }); + it("displays the results", function() { + mock = sandbox.mock(subject).expects("displayResults").once(); + subject.parseResponse(null, {rows: []}); + mock.verify(); + }); + }); + }); + it("calls the template rendering", function() { + templateSpy = sandbox.spy(); + window.matrix.template = templateSpy; + subject.displayResults(); + expect(templateSpy).to.have.been.calledOnce + }); + }); describe('#endpoint', function() { it('returns the path to the servers realtime endpoint', function() { expect(subject.endpoint()).to.eql('/realtime?ids=ga:&metrics=rt:pageviews&dimensions=rt:pageTitle,rt:pagePath&max-results=10&sort=-rt%3Apageviews'); From c94bd5f03097b858a7c36c53d286f4ea7c19b147 Mon Sep 17 00:00:00 2001 From: Mila Frerichs Date: Wed, 19 Aug 2015 11:50:40 +0200 Subject: [PATCH 05/13] Add chai-change to karma chai-change is a plugin for chai to test changes made by functions --- karma.conf.js | 2 +- package.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/karma.conf.js b/karma.conf.js index c2be70d..e5af5d7 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,7 +1,7 @@ module.exports = function(config) { config.set({ basePath: '', - frameworks: ['mocha', 'chai-jquery', 'jquery-2.1.0', 'chai', 'sinon-chai', 'fixture'], + frameworks: ['mocha', 'chai-jquery', 'jquery-2.1.0', 'chai-changes', 'chai', 'sinon-chai', 'fixture'], files: [ 'public/javascripts/vendor/d3.v3.min.js', 'public/javascripts/traffic.js', diff --git a/package.json b/package.json index b1594b7..cb0fec4 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "test": "./node_modules/karma/bin/karma start --single-run --browsers PhantomJS" }, "devDependencies": { + "chai-change": "^1.0.0", "karma": "^0.13.2", "karma-chai": "0.1.0", "karma-chai-jquery": "^1.0.0", From 8b489fecb5e0b80efff5f8c42c15afbabae59251 Mon Sep 17 00:00:00 2001 From: Mila Frerichs Date: Wed, 19 Aug 2015 11:51:17 +0200 Subject: [PATCH 06/13] Add more test to parseResponse and use chai-changes --- tests/contentSpec.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/contentSpec.js b/tests/contentSpec.js index 8fdbfbc..a5f45d7 100644 --- a/tests/contentSpec.js +++ b/tests/contentSpec.js @@ -67,6 +67,26 @@ describe('traffic', function() { subject.parseResponse(null, {rows: []}); mock.verify(); }); + it("adds new items to pages", function() { + sandbox.stub(subject, "displayResults"); + expect(function() { + return subject.pages.length; + }).to.change.by(1).when(function() { subject.parseResponse(null, data)}); + }); + it("adds new items to terms", function() { + sandbox.stub(subject, "displayResults"); + result = { title: 'Titel 1', url: "url 1", visits: 1 }; + subject.parseResponse(null, data); + expect(subject.pages[0]).to.eql(result); + }); + }); + context("no rows (no data from GA)", function() { + it("does not parse data", function() { + sandbox.stub(subject, "displayResults"); + expect(function() { + return subject.pages.length; + }).to.not.change.when(function() { subject.parseResponse(null, {})}); + }); }); }); it("calls the template rendering", function() { From aea873153f1814c90f638610bdf4248f198f0b67 Mon Sep 17 00:00:00 2001 From: Mila Frerichs Date: Wed, 19 Aug 2015 12:11:57 +0200 Subject: [PATCH 07/13] Use the historic endpoint to show the top pages from today show todays top pages and not the realtime top pages from the last 30 minutes --- public/javascripts/content.js | 9 +++++---- tests/contentSpec.js | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/public/javascripts/content.js b/public/javascripts/content.js index f55f50e..4aee4fa 100644 --- a/public/javascripts/content.js +++ b/public/javascripts/content.js @@ -8,12 +8,13 @@ el: false, endpoint: function(){ - return "/realtime?"+ + return "/historic?"+ "ids=ga:"+matrix.settings.profileId+"&"+ - "metrics=rt:pageviews&"+ - "dimensions=rt:pageTitle,rt:pagePath&"+ + "metrics=ga:pageviews&"+ + "dimensions=ga:pageTitle,ga:pagePath&"+ + "start-date=today&end-date=today&"+ "max-results=10&"+ - "sort=-rt%3Apageviews" + "sort=-ga%3Apageviews" }, parseResponse: function(error, data){ var i, _i; diff --git a/tests/contentSpec.js b/tests/contentSpec.js index a5f45d7..9cb7fa7 100644 --- a/tests/contentSpec.js +++ b/tests/contentSpec.js @@ -98,7 +98,7 @@ describe('traffic', function() { }); describe('#endpoint', function() { it('returns the path to the servers realtime endpoint', function() { - expect(subject.endpoint()).to.eql('/realtime?ids=ga:&metrics=rt:pageviews&dimensions=rt:pageTitle,rt:pagePath&max-results=10&sort=-rt%3Apageviews'); + expect(subject.endpoint()).to.eql('/historic?ids=ga:&metrics=ga:pageviews&dimensions=ga:pageTitle,ga:pagePath&start-date=today&end-date=today&max-results=10&sort=-ga%3Apageviews'); }); context('with profileId', function() { beforeEach(function() { @@ -107,7 +107,7 @@ describe('traffic', function() { }; }); it('returns correct profile Id in the endpoint path', function() { - expect(subject.endpoint()).to.eql('/realtime?ids=ga:Test&metrics=rt:pageviews&dimensions=rt:pageTitle,rt:pagePath&max-results=10&sort=-rt%3Apageviews'); + expect(subject.endpoint()).to.eql('/historic?ids=ga:Test&metrics=ga:pageviews&dimensions=ga:pageTitle,ga:pagePath&start-date=today&end-date=today&max-results=10&sort=-ga%3Apageviews'); }); }); }); From aa11b8bee561d6e2231e53c25a4de6d17f489621 Mon Sep 17 00:00:00 2001 From: Mila Frerichs Date: Wed, 19 Aug 2015 13:18:08 +0200 Subject: [PATCH 08/13] Add dataHelper to find objects in arrays by url --- karma.conf.js | 1 + public/index.html | 1 + public/javascripts/helper/dataHelper.js | 12 +++++++++++ tests/dataHelperSpec.js | 28 +++++++++++++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 public/javascripts/helper/dataHelper.js create mode 100644 tests/dataHelperSpec.js diff --git a/karma.conf.js b/karma.conf.js index e5af5d7..b7d051d 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -6,6 +6,7 @@ module.exports = function(config) { 'public/javascripts/vendor/d3.v3.min.js', 'public/javascripts/traffic.js', 'public/javascripts/content.js', + 'public/javascripts/helper/dataHelper.js', 'tests/**/*Spec.js', 'tests/fixtures/**/*' ], diff --git a/public/index.html b/public/index.html index 973ce42..8775391 100644 --- a/public/index.html +++ b/public/index.html @@ -61,6 +61,7 @@

Most popular pages

+ diff --git a/public/javascripts/helper/dataHelper.js b/public/javascripts/helper/dataHelper.js new file mode 100644 index 0000000..3bb3669 --- /dev/null +++ b/public/javascripts/helper/dataHelper.js @@ -0,0 +1,12 @@ +window.dataHelper = { + findWithUrl: function(data, url) { + var i, dataLength = data.length; + for(i=0;i Date: Wed, 19 Aug 2015 13:20:47 +0200 Subject: [PATCH 09/13] Add deviceCategory to popular pages request we want to show how many users are mobile or desktop users so we add the deviceCategory to the dimensions and change the column for the actual visitor count --- public/javascripts/content.js | 13 +++++++------ tests/contentSpec.js | 6 +++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/public/javascripts/content.js b/public/javascripts/content.js index 4aee4fa..ab88ee9 100644 --- a/public/javascripts/content.js +++ b/public/javascripts/content.js @@ -11,21 +11,22 @@ return "/historic?"+ "ids=ga:"+matrix.settings.profileId+"&"+ "metrics=ga:pageviews&"+ - "dimensions=ga:pageTitle,ga:pagePath&"+ + "dimensions=ga:pageTitle,ga:pagePath,ga:deviceCategory&"+ "start-date=today&end-date=today&"+ - "max-results=10&"+ + "max-results=1000&"+ "sort=-ga%3Apageviews" }, parseResponse: function(error, data){ - var i, _i; + var i, _i, + titleColumn = 0, urlColumn= 1, visitsColumn = 3; if(error) { return -1; } if(!data.hasOwnProperty("rows")) { return -1; } content.pages = []; for(i=0,_i=data.rows.length; i<_i; i++){ content.pages.push({ - title: data.rows[i][0], - url: data.rows[i][1], - visits: parseInt(data.rows[i][2]) + title: data.rows[i][titleColumn], + url: data.rows[i][urlColumn], + visits: parseInt(data.rows[i][visitsColumn]) }); } diff --git a/tests/contentSpec.js b/tests/contentSpec.js index 9cb7fa7..76bde53 100644 --- a/tests/contentSpec.js +++ b/tests/contentSpec.js @@ -59,7 +59,7 @@ describe('traffic', function() { context("no error parsing json", function() { context("has data from GA", function() { beforeEach(function() { - data = { rows: [["Titel 1","url 1","1"]] }; + data = { rows: [["Titel 1","url 1","DESKTOP","1"]] }; subject.pages = []; }); it("displays the results", function() { @@ -98,7 +98,7 @@ describe('traffic', function() { }); describe('#endpoint', function() { it('returns the path to the servers realtime endpoint', function() { - expect(subject.endpoint()).to.eql('/historic?ids=ga:&metrics=ga:pageviews&dimensions=ga:pageTitle,ga:pagePath&start-date=today&end-date=today&max-results=10&sort=-ga%3Apageviews'); + expect(subject.endpoint()).to.eql('/historic?ids=ga:&metrics=ga:pageviews&dimensions=ga:pageTitle,ga:pagePath,ga:deviceCategory&start-date=today&end-date=today&max-results=1000&sort=-ga%3Apageviews'); }); context('with profileId', function() { beforeEach(function() { @@ -107,7 +107,7 @@ describe('traffic', function() { }; }); it('returns correct profile Id in the endpoint path', function() { - expect(subject.endpoint()).to.eql('/historic?ids=ga:Test&metrics=ga:pageviews&dimensions=ga:pageTitle,ga:pagePath&start-date=today&end-date=today&max-results=10&sort=-ga%3Apageviews'); + expect(subject.endpoint()).to.eql('/historic?ids=ga:Test&metrics=ga:pageviews&dimensions=ga:pageTitle,ga:pagePath,ga:deviceCategory&start-date=today&end-date=today&max-results=1000&sort=-ga%3Apageviews'); }); }); }); From 5c767274df8f3321c792a42351ba5e981756f0cf Mon Sep 17 00:00:00 2001 From: Mila Frerichs Date: Wed, 19 Aug 2015 14:44:07 +0200 Subject: [PATCH 10/13] Refactor content parseResponse use a parseData method to actually parse the data --- public/javascripts/content.js | 12 ++++++----- tests/contentSpec.js | 39 +++++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/public/javascripts/content.js b/public/javascripts/content.js index ab88ee9..5889525 100644 --- a/public/javascripts/content.js +++ b/public/javascripts/content.js @@ -16,12 +16,9 @@ "max-results=1000&"+ "sort=-ga%3Apageviews" }, - parseResponse: function(error, data){ + parseData: function(data) { var i, _i, titleColumn = 0, urlColumn= 1, visitsColumn = 3; - if(error) { return -1; } - if(!data.hasOwnProperty("rows")) { return -1; } - content.pages = []; for(i=0,_i=data.rows.length; i<_i; i++){ content.pages.push({ title: data.rows[i][titleColumn], @@ -29,7 +26,12 @@ visits: parseInt(data.rows[i][visitsColumn]) }); } - + }, + parseResponse: function(error, data){ + if(error) { return -1; } + if(!data.hasOwnProperty("rows")) { return -1; } + content.pages = []; + content.parseData(data); content.displayResults(); }, displayResults: function(){ diff --git a/tests/contentSpec.js b/tests/contentSpec.js index 76bde53..38f9ea3 100644 --- a/tests/contentSpec.js +++ b/tests/contentSpec.js @@ -58,29 +58,26 @@ describe('traffic', function() { }); context("no error parsing json", function() { context("has data from GA", function() { - beforeEach(function() { - data = { rows: [["Titel 1","url 1","DESKTOP","1"]] }; - subject.pages = []; - }); it("displays the results", function() { mock = sandbox.mock(subject).expects("displayResults").once(); subject.parseResponse(null, {rows: []}); mock.verify(); }); - it("adds new items to pages", function() { + it("parses the data", function() { + data = {rows: []}; sandbox.stub(subject, "displayResults"); - expect(function() { - return subject.pages.length; - }).to.change.by(1).when(function() { subject.parseResponse(null, data)}); - }); - it("adds new items to terms", function() { - sandbox.stub(subject, "displayResults"); - result = { title: 'Titel 1', url: "url 1", visits: 1 }; + mock = sandbox.mock(subject).expects("parseData").withArgs(data).once(); subject.parseResponse(null, data); - expect(subject.pages[0]).to.eql(result); + mock.verify(); }); }); context("no rows (no data from GA)", function() { + it("does not call parseData", function() { + sandbox.stub(subject, "displayResults"); + mock = sandbox.mock(subject).expects("parseData").never(); + subject.parseResponse(null, {}); + mock.verify(); + }); it("does not parse data", function() { sandbox.stub(subject, "displayResults"); expect(function() { @@ -96,6 +93,22 @@ describe('traffic', function() { expect(templateSpy).to.have.been.calledOnce }); }); + describe('#parseData', function() { + beforeEach(function() { + data = { rows: [["Titel 1","url 1","DESKTOP","1"]] }; + subject.pages = []; + }); + it("adds new items to pages", function() { + expect(function() { + return subject.pages.length; + }).to.change.by(1).when(function() { subject.parseData(data)}); + }); + it("adds new items to terms", function() { + result = { title: 'Titel 1', url: "url 1", visits: 1 }; + subject.parseData(data); + expect(subject.pages[0]).to.eql(result); + }); + }); describe('#endpoint', function() { it('returns the path to the servers realtime endpoint', function() { expect(subject.endpoint()).to.eql('/historic?ids=ga:&metrics=ga:pageviews&dimensions=ga:pageTitle,ga:pagePath,ga:deviceCategory&start-date=today&end-date=today&max-results=1000&sort=-ga%3Apageviews'); From e4c4ec202baf4f1ede844cf788689193e334f2f9 Mon Sep 17 00:00:00 2001 From: Mila Frerichs Date: Wed, 19 Aug 2015 15:19:17 +0200 Subject: [PATCH 11/13] Add aggregation for mobile and desktop visitors update the pages where the url exists for the next result from GA and update the visits accordingly for now fesktop views come first from GA so mobile gets updated. needs a few adjustments: - reorder for overall count not only desktop count - evaluate the max-results param for the API call (1000 might be too much) - tablet needs to be incorperated into mobile on the aggregation --- public/index.html | 3 ++- public/javascripts/content.js | 23 +++++++++++++++++------ tests/contentSpec.js | 10 ++++++++-- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/public/index.html b/public/index.html index 8775391..c1db397 100644 --- a/public/index.html +++ b/public/index.html @@ -96,7 +96,8 @@

Most popular pages

  • {{ title }} - visits: {{ visits }} + mobile: {{ visits.mobile }} + desktop: {{ visits.desktop}}
  • {{/pages}} diff --git a/public/javascripts/content.js b/public/javascripts/content.js index 5889525..05d673c 100644 --- a/public/javascripts/content.js +++ b/public/javascripts/content.js @@ -18,13 +18,24 @@ }, parseData: function(data) { var i, _i, - titleColumn = 0, urlColumn= 1, visitsColumn = 3; + row, url, device, oldRow, visits, visitsDevice, + titleColumn = 0, urlColumn= 1, deviceColumn = 2, visitsColumn = 3; for(i=0,_i=data.rows.length; i<_i; i++){ - content.pages.push({ - title: data.rows[i][titleColumn], - url: data.rows[i][urlColumn], - visits: parseInt(data.rows[i][visitsColumn]) - }); + row = data.rows[i]; + url = row[urlColumn]; + device = row[deviceColumn].toLowerCase(); + visits = parseInt(row[visitsColumn]); + if(oldRow = window.dataHelper.findWithUrl(content.pages, url)) { + oldRow.visits[device] += visits; + }else { + visitsDevice = { desktop: 0, mobile: 0 }; + visitsDevice[device] += visits; + content.pages.push({ + title: data.rows[i][titleColumn], + url: data.rows[i][urlColumn], + visits: visitsDevice + }); + } } }, parseResponse: function(error, data){ diff --git a/tests/contentSpec.js b/tests/contentSpec.js index 38f9ea3..63d8bac 100644 --- a/tests/contentSpec.js +++ b/tests/contentSpec.js @@ -103,8 +103,14 @@ describe('traffic', function() { return subject.pages.length; }).to.change.by(1).when(function() { subject.parseData(data)}); }); - it("adds new items to terms", function() { - result = { title: 'Titel 1', url: "url 1", visits: 1 }; + it("adds new items to pages", function() { + result = { title: 'Titel 1', url: "url 1", visits: { desktop: 1, mobile: 0 } }; + subject.parseData(data); + expect(subject.pages[0]).to.eql(result); + }); + it("updates items for the same url", function() { + data = { rows: [["Titel 1","url 1","DESKTOP","1"], ["Titel 1","url 1","MOBILE","1"]] }; + result = { title: 'Titel 1', url: "url 1", visits: { desktop: 1, mobile: 1 } }; subject.parseData(data); expect(subject.pages[0]).to.eql(result); }); From 2e8c3d7ef2d5e2763c7f1a602ffd595f2261f6ad Mon Sep 17 00:00:00 2001 From: Mila Frerichs Date: Wed, 19 Aug 2015 15:28:01 +0200 Subject: [PATCH 12/13] Add whitespace --- public/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index c1db397..33a3abb 100644 --- a/public/index.html +++ b/public/index.html @@ -97,7 +97,7 @@

    Most popular pages

    {{ title }} mobile: {{ visits.mobile }} - desktop: {{ visits.desktop}} + desktop: {{ visits.desktop }} {{/pages}} From 37b1a064e3ce5fb78cfa71d4dcb54f76a047b78d Mon Sep 17 00:00:00 2001 From: Mila Frerichs Date: Wed, 19 Aug 2015 15:46:20 +0200 Subject: [PATCH 13/13] Update package.json to include correct package --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cb0fec4..f7e4528 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,9 @@ "test": "./node_modules/karma/bin/karma start --single-run --browsers PhantomJS" }, "devDependencies": { - "chai-change": "^1.0.0", "karma": "^0.13.2", "karma-chai": "0.1.0", + "karma-chai-changes": "0.0.1", "karma-chai-jquery": "^1.0.0", "karma-coverage": "^0.4.2", "karma-coveralls": "^1.1.2",