Skip to content

Commit

Permalink
Merge branch 'most-popular-pages' into staging
Browse files Browse the repository at this point in the history
Conflicts:
	public/index.html
  • Loading branch information
milafrerichs committed Aug 19, 2015
2 parents 8f4d6aa + 37b1a06 commit 0c2e458
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 16 deletions.
4 changes: 3 additions & 1 deletion 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/vendor/raphael-min.js',
Expand All @@ -10,6 +10,8 @@ module.exports = function(config) {
'public/javascripts/vendor/handlebars-v3.0.3.js',
'public/javascripts/landing-pages.js',
'public/javascripts/traffic.js',
'public/javascripts/content.js',
'public/javascripts/helper/dataHelper.js',
'tests/**/*Spec.js',
'tests/fixtures/**/*'
],
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -9,6 +9,7 @@
"devDependencies": {
"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",
Expand Down
4 changes: 3 additions & 1 deletion public/index.html
Expand Up @@ -71,6 +71,7 @@ <h2 class="brick-heading">Most popular pages</h2>
<script src="javascripts/vendor/bezier.js"></script>

<script src="javascripts/helpers/helper.js"></script>
<script src="javascripts/helper/dataHelper.js"></script>
<script src="javascripts/sparkline.js"></script>
<script src="javascripts/landing-pages.js"></script>
<script src="javascripts/search.js"></script>
Expand Down Expand Up @@ -105,7 +106,8 @@ <h2 class="brick-heading">Most popular pages</h2>
<li>
<a href="http://{{ url }}" target="_blank">{{ title }}</a>
<em>
visits: {{ visits }}
mobile: {{ visits.mobile }}
desktop: {{ visits.desktop }}
</em>
</li>
{{/pages}}
Expand Down
47 changes: 33 additions & 14 deletions public/javascripts/content.js
Expand Up @@ -7,23 +7,42 @@
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 "/historic?"+
"ids=ga:"+matrix.settings.profileId+"&"+
"metrics=ga:pageviews&"+
"dimensions=ga:pageTitle,ga:pagePath,ga:deviceCategory&"+
"start-date=today&end-date=today&"+
"max-results=1000&"+
"sort=-ga%3Apageviews"
},
parseResponse: function(data){
var i, _i;

content.pages = [];
parseData: function(data) {
var i, _i,
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][0],//.split(' — ').slice(0,-1).join(' - '),
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)) + "%"
});
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){
if(error) { return -1; }
if(!data.hasOwnProperty("rows")) { return -1; }
content.pages = [];
content.parseData(data);
content.displayResults();
},
displayResults: function(){
Expand Down
12 changes: 12 additions & 0 deletions public/javascripts/helper/dataHelper.js
@@ -0,0 +1,12 @@
window.dataHelper = {
findWithUrl: function(data, url) {
var i, dataLength = data.length;
for(i=0;i<dataLength;i++) {
result = data[i];
if(result.url === url) {
return result;
}
}
return undefined;
}
}
133 changes: 133 additions & 0 deletions tests/contentSpec.js
@@ -0,0 +1,133 @@
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('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('#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('#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() {
it("displays the results", function() {
mock = sandbox.mock(subject).expects("displayResults").once();
subject.parseResponse(null, {rows: []});
mock.verify();
});
it("parses the data", function() {
data = {rows: []};
sandbox.stub(subject, "displayResults");
mock = sandbox.mock(subject).expects("parseData").withArgs(data).once();
subject.parseResponse(null, data);
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() {
return subject.pages.length;
}).to.not.change.when(function() { subject.parseResponse(null, {})});
});
});
});
it("calls the template rendering", function() {
templateSpy = sandbox.spy();
window.matrix.template = templateSpy;
subject.displayResults();
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 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);
});
});
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');
});
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('/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');
});
});
});
});
28 changes: 28 additions & 0 deletions tests/dataHelperSpec.js
@@ -0,0 +1,28 @@
describe('dataHelper', function() {
beforeEach(function() {
subject = window.dataHelper;
sandbox = sinon.sandbox.create();
});
afterEach(function() {
sandbox.restore();
server.restore();
});
describe('findWithUrl', function() {
beforeEach(function() {
entry1 = { url: "test.de", title: "Test" };
entry2 = { url: "test2.de", title: "Test 2" };
data = [entry1, entry2];
});
it("returns object with the same url", function() {
expect(subject.findWithUrl(data, "test.de")).to.eql(entry1);
});
it("returns undefined if url not found", function() {
expect(subject.findWithUrl(data, "tost.de")).to.eql(undefined);
});
it("returns the first result not every", function() {
entry2 = { url: "test.de", title: "Test 2" };
data = [entry1, entry2];
expect(subject.findWithUrl(data, "test.de")).to.eql(entry1);
});
});
});

0 comments on commit 0c2e458

Please sign in to comment.