Commit 2ef7c6f0 authored by Luke "Jared" Bennett's avatar Luke "Jared" Bennett

Fixed specs

parent 1e2246e7
...@@ -3,6 +3,15 @@ ...@@ -3,6 +3,15 @@
import sqljs from 'sql.js'; import sqljs from 'sql.js';
import { template as _template } from 'underscore'; import { template as _template } from 'underscore';
const PREVIEW_TEMPLATE = _template(`
<div class="panel panel-default">
<div class="panel-heading"><%- name %></div>
<div class="panel-body">
<img class="img-thumbnail" src="data:image/png;base64,<%- image %>"/>
</div>
</div>
`);
class BalsamiqViewer { class BalsamiqViewer {
constructor(viewer) { constructor(viewer) {
this.viewer = viewer; this.viewer = viewer;
...@@ -18,23 +27,23 @@ class BalsamiqViewer { ...@@ -18,23 +27,23 @@ class BalsamiqViewer {
xhr.onload = this.renderFile.bind(this); xhr.onload = this.renderFile.bind(this);
xhr.onerror = BalsamiqViewer.onError; xhr.onerror = BalsamiqViewer.onError;
this.spinner.start();
xhr.send(); xhr.send();
} }
renderFile(loadEvent) { renderFile(loadEvent) {
this.spinner.stop();
const container = document.createElement('ul'); const container = document.createElement('ul');
this.initDatabase(loadEvent.target.response); this.initDatabase(loadEvent.target.response);
const previews = this.getPreviews(); const previews = this.getPreviews();
const renderedPreviews = previews.map(preview => this.renderPreview(preview)); previews.forEach((preview) => {
const renderedPreview = this.renderPreview(preview);
container.innerHTML = renderedPreviews.join(''); container.appendChild(renderedPreview);
container.classList.add('list-inline', 'previews'); });
container.classList.add('list-inline');
container.classList.add('previews');
this.viewer.appendChild(container); this.viewer.appendChild(container);
} }
...@@ -51,8 +60,10 @@ class BalsamiqViewer { ...@@ -51,8 +60,10 @@ class BalsamiqViewer {
return thumbnails[0].values.map(BalsamiqViewer.parsePreview); return thumbnails[0].values.map(BalsamiqViewer.parsePreview);
} }
getTitle(resourceID) { getResource(resourceID) {
return this.database.exec(`SELECT * FROM resources WHERE id = '${resourceID}'`); const resources = this.database.exec(`SELECT * FROM resources WHERE id = '${resourceID}'`);
return resources[0];
} }
renderPreview(preview) { renderPreview(preview) {
...@@ -61,15 +72,15 @@ class BalsamiqViewer { ...@@ -61,15 +72,15 @@ class BalsamiqViewer {
previewElement.classList.add('preview'); previewElement.classList.add('preview');
previewElement.innerHTML = this.renderTemplate(preview); previewElement.innerHTML = this.renderTemplate(preview);
return previewElement.outerHTML; return previewElement;
} }
renderTemplate(preview) { renderTemplate(preview) {
const title = this.getTitle(preview.resourceID); const resource = this.getResource(preview.resourceID);
const name = BalsamiqViewer.parseTitle(title); const name = BalsamiqViewer.parseTitle(resource);
const image = preview.image; const image = preview.image;
const template = BalsamiqViewer.PREVIEW_TEMPLATE({ const template = PREVIEW_TEMPLATE({
name, name,
image, image,
}); });
...@@ -81,8 +92,16 @@ class BalsamiqViewer { ...@@ -81,8 +92,16 @@ class BalsamiqViewer {
return JSON.parse(preview[1]); return JSON.parse(preview[1]);
} }
static parseTitle(title) { /*
return JSON.parse(title[0].values[0][2]).name; * resource = {
* columns: ['ID', 'BRANCHID', 'ATTRIBUTES', 'DATA'],
* values: [['id', 'branchId', 'attributes', 'data']],
* }
*
* 'attributes' being a JSON string containing the `name` property.
*/
static parseTitle(resource) {
return JSON.parse(resource.values[0][2]).name;
} }
static onError() { static onError() {
...@@ -92,13 +111,4 @@ class BalsamiqViewer { ...@@ -92,13 +111,4 @@ class BalsamiqViewer {
} }
} }
BalsamiqViewer.PREVIEW_TEMPLATE = _template(`
<div class="panel panel-default">
<div class="panel-heading"><%- name %></div>
<div class="panel-body">
<img class="img-thumbnail" src="data:image/png;base64,<%- image %>"/>
</div>
</div>
`);
export default BalsamiqViewer; export default BalsamiqViewer;
- content_for :page_specific_javascripts do - content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('balsamiq_viewer') = page_specific_javascript_bundle_tag('balsamiq_viewer')
.file-content.balsamiq-viewer#js-balsamiq-viewer{ data: { endpoint: namespace_project_raw_path(@project.namespace, @project, @id) } } .file-content.balsamiq-viewer#js-balsamiq-viewer{ data: { endpoint: blob_raw_url } }
import sqljs from 'sql.js'; import sqljs from 'sql.js';
import BalsamiqViewer from '~/blob/balsamiq/balsamiq_viewer'; import BalsamiqViewer from '~/blob/balsamiq/balsamiq_viewer';
import * as spinnerSrc from '~/spinner';
import ClassSpecHelper from '../../helpers/class_spec_helper'; import ClassSpecHelper from '../../helpers/class_spec_helper';
describe('BalsamiqViewer', () => { describe('BalsamiqViewer', () => {
...@@ -17,8 +16,6 @@ describe('BalsamiqViewer', () => { ...@@ -17,8 +16,6 @@ describe('BalsamiqViewer', () => {
}, },
}; };
spyOn(spinnerSrc, 'default');
balsamiqViewer = new BalsamiqViewer(viewer); balsamiqViewer = new BalsamiqViewer(viewer);
}); });
...@@ -29,38 +26,23 @@ describe('BalsamiqViewer', () => { ...@@ -29,38 +26,23 @@ describe('BalsamiqViewer', () => {
it('should set .endpoint', () => { it('should set .endpoint', () => {
expect(balsamiqViewer.endpoint).toBe(endpoint); expect(balsamiqViewer.endpoint).toBe(endpoint);
}); });
it('should instantiate Spinner', () => {
expect(spinnerSrc.default).toHaveBeenCalledWith(viewer);
});
it('should set .spinner', () => {
expect(balsamiqViewer.spinner).toEqual(jasmine.any(spinnerSrc.default));
});
}); });
describe('loadFile', () => { describe('loadFile', () => {
let xhr; let xhr;
let spinner;
beforeEach(() => { beforeEach(() => {
endpoint = 'endpoint'; endpoint = 'endpoint';
xhr = jasmine.createSpyObj('xhr', ['open', 'send']); xhr = jasmine.createSpyObj('xhr', ['open', 'send']);
spinner = jasmine.createSpyObj('spinner', ['start']);
balsamiqViewer = jasmine.createSpyObj('balsamiqViewer', ['renderFile']); balsamiqViewer = jasmine.createSpyObj('balsamiqViewer', ['renderFile']);
balsamiqViewer.endpoint = endpoint; balsamiqViewer.endpoint = endpoint;
balsamiqViewer.spinner = spinner;
spyOn(window, 'XMLHttpRequest').and.returnValue(xhr); spyOn(window, 'XMLHttpRequest').and.returnValue(xhr);
BalsamiqViewer.prototype.loadFile.call(balsamiqViewer); BalsamiqViewer.prototype.loadFile.call(balsamiqViewer);
}); });
it('should instantiate XMLHttpRequest', () => {
expect(window.XMLHttpRequest).toHaveBeenCalled();
});
it('should call .open', () => { it('should call .open', () => {
expect(xhr.open).toHaveBeenCalledWith('GET', endpoint, true); expect(xhr.open).toHaveBeenCalledWith('GET', endpoint, true);
}); });
...@@ -69,25 +51,12 @@ describe('BalsamiqViewer', () => { ...@@ -69,25 +51,12 @@ describe('BalsamiqViewer', () => {
expect(xhr.responseType).toBe('arraybuffer'); expect(xhr.responseType).toBe('arraybuffer');
}); });
it('should set .onload', () => {
expect(xhr.onload).toEqual(jasmine.any(Function));
});
it('should set .onerror', () => {
expect(xhr.onerror).toBe(BalsamiqViewer.onError);
});
it('should call spinner.start', () => {
expect(spinner.start).toHaveBeenCalled();
});
it('should call .send', () => { it('should call .send', () => {
expect(xhr.send).toHaveBeenCalled(); expect(xhr.send).toHaveBeenCalled();
}); });
}); });
describe('renderFile', () => { describe('renderFile', () => {
let spinner;
let container; let container;
let loadEvent; let loadEvent;
let previews; let previews;
...@@ -95,12 +64,10 @@ describe('BalsamiqViewer', () => { ...@@ -95,12 +64,10 @@ describe('BalsamiqViewer', () => {
beforeEach(() => { beforeEach(() => {
loadEvent = { target: { response: {} } }; loadEvent = { target: { response: {} } };
viewer = jasmine.createSpyObj('viewer', ['appendChild']); viewer = jasmine.createSpyObj('viewer', ['appendChild']);
spinner = jasmine.createSpyObj('spinner', ['stop']); previews = [document.createElement('ul'), document.createElement('ul')];
previews = [0, 1, 2];
balsamiqViewer = jasmine.createSpyObj('balsamiqViewer', ['initDatabase', 'getPreviews', 'renderPreview']); balsamiqViewer = jasmine.createSpyObj('balsamiqViewer', ['initDatabase', 'getPreviews', 'renderPreview']);
balsamiqViewer.viewer = viewer; balsamiqViewer.viewer = viewer;
balsamiqViewer.spinner = spinner;
balsamiqViewer.getPreviews.and.returnValue(previews); balsamiqViewer.getPreviews.and.returnValue(previews);
balsamiqViewer.renderPreview.and.callFake(preview => preview); balsamiqViewer.renderPreview.and.callFake(preview => preview);
...@@ -111,10 +78,6 @@ describe('BalsamiqViewer', () => { ...@@ -111,10 +78,6 @@ describe('BalsamiqViewer', () => {
BalsamiqViewer.prototype.renderFile.call(balsamiqViewer, loadEvent); BalsamiqViewer.prototype.renderFile.call(balsamiqViewer, loadEvent);
}); });
it('should call spinner.stop', () => {
expect(spinner.stop).toHaveBeenCalled();
});
it('should call .initDatabase', () => { it('should call .initDatabase', () => {
expect(balsamiqViewer.initDatabase).toHaveBeenCalledWith(loadEvent.target.response); expect(balsamiqViewer.initDatabase).toHaveBeenCalledWith(loadEvent.target.response);
}); });
...@@ -126,15 +89,15 @@ describe('BalsamiqViewer', () => { ...@@ -126,15 +89,15 @@ describe('BalsamiqViewer', () => {
it('should call .renderPreview for each preview', () => { it('should call .renderPreview for each preview', () => {
const allArgs = balsamiqViewer.renderPreview.calls.allArgs(); const allArgs = balsamiqViewer.renderPreview.calls.allArgs();
expect(allArgs.length).toBe(3); expect(allArgs.length).toBe(2);
previews.forEach((preview, i) => { previews.forEach((preview, i) => {
expect(allArgs[i][0]).toBe(preview); expect(allArgs[i][0]).toBe(preview);
}); });
}); });
it('should set .innerHTML', () => { it('should set the container HTML', () => {
expect(container.innerHTML).toBe('012'); expect(container.innerHTML).toBe('<ul></ul><ul></ul>');
}); });
it('should add inline preview classes', () => { it('should add inline preview classes', () => {
...@@ -216,16 +179,16 @@ describe('BalsamiqViewer', () => { ...@@ -216,16 +179,16 @@ describe('BalsamiqViewer', () => {
}); });
}); });
describe('getTitle', () => { describe('getResource', () => {
let database; let database;
let resourceID; let resourceID;
let resource; let resource;
let getTitle; let getResource;
beforeEach(() => { beforeEach(() => {
database = jasmine.createSpyObj('database', ['exec']); database = jasmine.createSpyObj('database', ['exec']);
resourceID = 4; resourceID = 4;
resource = 'resource'; resource = ['resource'];
balsamiqViewer = { balsamiqViewer = {
database, database,
...@@ -233,7 +196,7 @@ describe('BalsamiqViewer', () => { ...@@ -233,7 +196,7 @@ describe('BalsamiqViewer', () => {
database.exec.and.returnValue(resource); database.exec.and.returnValue(resource);
getTitle = BalsamiqViewer.prototype.getTitle.call(balsamiqViewer, resourceID); getResource = BalsamiqViewer.prototype.getResource.call(balsamiqViewer, resourceID);
}); });
it('should call database.exec', () => { it('should call database.exec', () => {
...@@ -241,7 +204,7 @@ describe('BalsamiqViewer', () => { ...@@ -241,7 +204,7 @@ describe('BalsamiqViewer', () => {
}); });
it('should return the selected resource', () => { it('should return the selected resource', () => {
expect(getTitle).toBe(resource); expect(getResource).toBe(resource[0]);
}); });
}); });
...@@ -267,10 +230,6 @@ describe('BalsamiqViewer', () => { ...@@ -267,10 +230,6 @@ describe('BalsamiqViewer', () => {
renderPreview = BalsamiqViewer.prototype.renderPreview.call(balsamiqViewer, preview); renderPreview = BalsamiqViewer.prototype.renderPreview.call(balsamiqViewer, preview);
}); });
it('should call document.createElement', () => {
expect(document.createElement).toHaveBeenCalledWith('li');
});
it('should call classList.add', () => { it('should call classList.add', () => {
expect(previewElement.classList.add).toHaveBeenCalledWith('preview'); expect(previewElement.classList.add).toHaveBeenCalledWith('preview');
}); });
...@@ -283,22 +242,22 @@ describe('BalsamiqViewer', () => { ...@@ -283,22 +242,22 @@ describe('BalsamiqViewer', () => {
expect(previewElement.innerHTML).toBe(innerHTML); expect(previewElement.innerHTML).toBe(innerHTML);
}); });
it('should return .outerHTML', () => { it('should return element', () => {
expect(renderPreview).toBe(previewElement.outerHTML); expect(renderPreview).toBe(previewElement);
}); });
}); });
describe('renderTemplate', () => { describe('renderTemplate', () => {
let preview; let preview;
let name; let name;
let title; let resource;
let template; let template;
let renderTemplate; let renderTemplate;
beforeEach(() => { beforeEach(() => {
preview = { resourceID: 1, image: 'image' }; preview = { resourceID: 1, image: 'image' };
name = 'name'; name = 'name';
title = 'title'; resource = 'resource';
template = ` template = `
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading">name</div> <div class="panel-heading">name</div>
...@@ -308,32 +267,24 @@ describe('BalsamiqViewer', () => { ...@@ -308,32 +267,24 @@ describe('BalsamiqViewer', () => {
</div> </div>
`; `;
balsamiqViewer = jasmine.createSpyObj('balsamiqViewer', ['getTitle']); balsamiqViewer = jasmine.createSpyObj('balsamiqViewer', ['getResource']);
spyOn(BalsamiqViewer, 'parseTitle').and.returnValue(name); spyOn(BalsamiqViewer, 'parseTitle').and.returnValue(name);
spyOn(BalsamiqViewer, 'PREVIEW_TEMPLATE').and.returnValue(template); balsamiqViewer.getResource.and.returnValue(resource);
balsamiqViewer.getTitle.and.returnValue(title);
renderTemplate = BalsamiqViewer.prototype.renderTemplate.call(balsamiqViewer, preview); renderTemplate = BalsamiqViewer.prototype.renderTemplate.call(balsamiqViewer, preview);
}); });
it('should call .getTitle', () => { it('should call .getResource', () => {
expect(balsamiqViewer.getTitle).toHaveBeenCalledWith(preview.resourceID); expect(balsamiqViewer.getResource).toHaveBeenCalledWith(preview.resourceID);
}); });
it('should call .parseTitle', () => { it('should call .parseTitle', () => {
expect(BalsamiqViewer.parseTitle).toHaveBeenCalledWith(title); expect(BalsamiqViewer.parseTitle).toHaveBeenCalledWith(resource);
});
it('should call .PREVIEW_TEMPLATE', () => {
expect(BalsamiqViewer.PREVIEW_TEMPLATE).toHaveBeenCalledWith({
name,
image: preview.image,
});
}); });
it('should return the template string', function () { it('should return the template string', function () {
expect(renderTemplate.trim()).toBe(template.trim()); expect(renderTemplate.replace(/\s/g, '')).toEqual(template.replace(/\s/g, ''));
}); });
}); });
...@@ -351,10 +302,6 @@ describe('BalsamiqViewer', () => { ...@@ -351,10 +302,6 @@ describe('BalsamiqViewer', () => {
ClassSpecHelper.itShouldBeAStaticMethod(BalsamiqViewer, 'parsePreview'); ClassSpecHelper.itShouldBeAStaticMethod(BalsamiqViewer, 'parsePreview');
it('should call JSON.parse', () => {
expect(JSON.parse).toHaveBeenCalledWith(preview[1]);
});
it('should return the parsed JSON', () => { it('should return the parsed JSON', () => {
expect(parsePreview).toEqual(JSON.parse('{ "id": 1 }')); expect(parsePreview).toEqual(JSON.parse('{ "id": 1 }'));
}); });
...@@ -365,7 +312,7 @@ describe('BalsamiqViewer', () => { ...@@ -365,7 +312,7 @@ describe('BalsamiqViewer', () => {
let parseTitle; let parseTitle;
beforeEach(() => { beforeEach(() => {
title = [{ values: [['{}', '{}', '{"name":"name"}']] }]; title = { values: [['{}', '{}', '{"name":"name"}']] };
spyOn(JSON, 'parse').and.callThrough(); spyOn(JSON, 'parse').and.callThrough();
...@@ -374,22 +321,16 @@ describe('BalsamiqViewer', () => { ...@@ -374,22 +321,16 @@ describe('BalsamiqViewer', () => {
ClassSpecHelper.itShouldBeAStaticMethod(BalsamiqViewer, 'parsePreview'); ClassSpecHelper.itShouldBeAStaticMethod(BalsamiqViewer, 'parsePreview');
it('should call JSON.parse', () => {
expect(JSON.parse).toHaveBeenCalledWith(title[0].values[0][2]);
});
it('should return the name value', () => { it('should return the name value', () => {
expect(parseTitle).toBe('name'); expect(parseTitle).toBe('name');
}); });
}); });
describe('onError', () => { describe('onError', () => {
let onError;
beforeEach(() => { beforeEach(() => {
spyOn(window, 'Flash'); spyOn(window, 'Flash');
onError = BalsamiqViewer.onError(); BalsamiqViewer.onError();
}); });
ClassSpecHelper.itShouldBeAStaticMethod(BalsamiqViewer, 'onError'); ClassSpecHelper.itShouldBeAStaticMethod(BalsamiqViewer, 'onError');
...@@ -397,9 +338,5 @@ describe('BalsamiqViewer', () => { ...@@ -397,9 +338,5 @@ describe('BalsamiqViewer', () => {
it('should instantiate Flash', () => { it('should instantiate Flash', () => {
expect(window.Flash).toHaveBeenCalledWith('Balsamiq file could not be loaded.'); expect(window.Flash).toHaveBeenCalledWith('Balsamiq file could not be loaded.');
}); });
it('should return Flash', () => {
expect(onError).toEqual(jasmine.any(window.Flash));
});
}); });
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment