PrivateBin/PrivateBin

View on GitHub
js/test/TopNav.js

Summary

Maintainability
F
4 days
Test Coverage
'use strict';
var common = require('../common');

describe('TopNav', function () {
    describe('showViewButtons & hideViewButtons', function () {
        before(function () {
            cleanup();
        });

        it(
            'displays & hides navigation elements for viewing an existing paste',
            function () {
                var results = [];
                $('body').html(
                    '<nav class="navbar navbar-inverse navbar-static-top">' +
                    '<div id="navbar" class="navbar-collapse collapse"><ul ' +
                    'class="nav navbar-nav"><li><button id="newbutton" ' +
                    'type="button" class="hidden btn btn-warning navbar-btn">' +
                    '<span class="glyphicon glyphicon-file" aria-hidden="true">' +
                    '</span> New</button><button id="clonebutton" type="button"' +
                    ' class="hidden btn btn-warning navbar-btn">' +
                    '<span class="glyphicon glyphicon-duplicate" ' +
                    'aria-hidden="true"></span> Clone</button><button ' +
                    'id="rawtextbutton" type="button" class="hidden btn ' +
                    'btn-warning navbar-btn"><span class="glyphicon ' +
                    'glyphicon-text-background" aria-hidden="true"></span> ' +
                    'Raw text</button><button id="qrcodelink" type="button" ' +
                    'data-toggle="modal" data-target="#qrcodemodal" ' +
                    'class="hidden btn btn-warning navbar-btn"><span ' +
                    'class="glyphicon glyphicon-qrcode" aria-hidden="true">' +
                    '</span> QR code</button></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    $('#newbutton').hasClass('hidden') &&
                    $('#clonebutton').hasClass('hidden') &&
                    $('#rawtextbutton').hasClass('hidden') &&
                    $('#qrcodelink').hasClass('hidden')
                );
                $.PrivateBin.TopNav.showViewButtons();
                results.push(
                    !$('#newbutton').hasClass('hidden') &&
                    !$('#clonebutton').hasClass('hidden') &&
                    !$('#rawtextbutton').hasClass('hidden') &&
                    !$('#qrcodelink').hasClass('hidden')
                );
                $.PrivateBin.TopNav.hideViewButtons();
                results.push(
                    $('#newbutton').hasClass('hidden') &&
                    $('#clonebutton').hasClass('hidden') &&
                    $('#rawtextbutton').hasClass('hidden') &&
                    $('#qrcodelink').hasClass('hidden')
                );
                cleanup();
                assert.ok(results.every(element => element));
            }
        );
    });

    describe('showCreateButtons & hideCreateButtons', function () {
        before(function () {
            cleanup();
        });

        it(
            'displays & hides navigation elements for creating a paste',
            function () {
                var results = [];
                $('body').html(
                    '<nav><div id="navbar"><ul><li><button id="newbutton" ' +
                    'type="button" class="hidden">New</button></li><li><a ' +
                    'id="expiration" href="#" class="hidden">Expiration</a>' +
                    '</li><li><div id="burnafterreadingoption" class="hidden">' +
                    'Burn after reading</div></li><li><div id="opendiscussion' +
                    'option" class="hidden">Open discussion</div></li><li>' +
                    '<div id="password" class="hidden">Password</div></li>' +
                    '<li id="attach" class="hidden">Attach a file</li><li>' +
                    '<a id="formatter" href="#" class="hidden">Format</a>' +
                    '</li><li><button id="sendbutton" type="button" ' +
                    'class="hidden">Create</button></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    $('#sendbutton').hasClass('hidden') &&
                    $('#expiration').hasClass('hidden') &&
                    $('#formatter').hasClass('hidden') &&
                    $('#burnafterreadingoption').hasClass('hidden') &&
                    $('#opendiscussionoption').hasClass('hidden') &&
                    $('#newbutton').hasClass('hidden') &&
                    $('#password').hasClass('hidden') &&
                    $('#attach').hasClass('hidden')
                );
                $.PrivateBin.TopNav.showCreateButtons();
                results.push(
                    !$('#sendbutton').hasClass('hidden') &&
                    !$('#expiration').hasClass('hidden') &&
                    !$('#formatter').hasClass('hidden') &&
                    !$('#burnafterreadingoption').hasClass('hidden') &&
                    !$('#opendiscussionoption').hasClass('hidden') &&
                    !$('#newbutton').hasClass('hidden') &&
                    !$('#password').hasClass('hidden') &&
                    !$('#attach').hasClass('hidden')
                );
                $.PrivateBin.TopNav.hideCreateButtons();
                results.push(
                    $('#sendbutton').hasClass('hidden') &&
                    $('#expiration').hasClass('hidden') &&
                    $('#formatter').hasClass('hidden') &&
                    $('#burnafterreadingoption').hasClass('hidden') &&
                    $('#opendiscussionoption').hasClass('hidden') &&
                    $('#newbutton').hasClass('hidden') &&
                    $('#password').hasClass('hidden') &&
                    $('#attach').hasClass('hidden')
                );
                cleanup();
                assert.ok(results.every(element => element));
            }
        );
    });

    describe('showNewPasteButton', function () {
        before(function () {
            cleanup();
        });

        it(
            'displays the button for creating a paste',
            function () {
                var results = [];
                $('body').html(
                    '<nav><div id="navbar"><ul><li><button id="newbutton" type=' +
                    '"button" class="hidden">New</button></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    $('#newbutton').hasClass('hidden')
                );
                $.PrivateBin.TopNav.showNewPasteButton();
                results.push(
                    !$('#newbutton').hasClass('hidden')
                );
                cleanup();
                assert.ok(results.every(element => element));
            }
        );
    });

    describe('hideCloneButton', function () {
        before(function () {
            cleanup();
        });

        it(
            'hides the button for cloning a paste',
            function () {
                var results = [];
                $('body').html(
                    '<nav><div id="navbar"><ul><li><button id="clonebutton" ' +
                    'type="button" class="btn btn-warning navbar-btn">' +
                    '<span class="glyphicon glyphicon-duplicate" aria-hidden=' +
                    '"true"></span> Clone</button></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    !$('#clonebutton').hasClass('hidden')
                );
                $.PrivateBin.TopNav.hideCloneButton();
                results.push(
                    $('#clonebutton').hasClass('hidden')
                );
                cleanup();
                assert.ok(results.every(element => element));
            }
        );
    });

    describe('hideRawButton', function () {
        before(function () {
            cleanup();
        });

        it(
            'hides the raw text button',
            function () {
                var results = [];
                $('body').html(
                    '<nav><div id="navbar"><ul><li><button ' +
                    'id="rawtextbutton" type="button" class="btn ' +
                    'btn-warning navbar-btn"><span class="glyphicon ' +
                    'glyphicon-text-background" aria-hidden="true"></span> ' +
                    'Raw text</button></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    !$('#rawtextbutton').hasClass('hidden')
                );
                $.PrivateBin.TopNav.hideRawButton();
                results.push(
                    $('#rawtextbutton').hasClass('hidden')
                );
                cleanup();
                assert.ok(results.every(element => element));
            }
        );
    });

    describe('hideFileSelector', function () {
        before(function () {
            cleanup();
        });

        it(
            'hides the file attachment selection button',
            function () {
                var results = [];
                $('body').html(
                    '<nav><div id="navbar"><ul><li id="attach" class="hidden ' +
                    'dropdown"><a href="#" class="dropdown-toggle" data-' +
                    'toggle="dropdown" role="button" aria-haspopup="true" ' +
                    'aria-expanded="false">Attach a file <span class="caret">' +
                    '</span></a><ul class="dropdown-menu"><li id="filewrap">' +
                    '<div><input type="file" id="file" name="file" /></div>' +
                    '</li><li id="customattachment" class="hidden"></li><li>' +
                    '<a id="fileremovebutton"  href="#">Remove attachment</a>' +
                    '</li></ul></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    !$('#filewrap').hasClass('hidden')
                );
                $.PrivateBin.TopNav.hideFileSelector();
                results.push(
                    $('#filewrap').hasClass('hidden')
                );
                cleanup();
                assert.ok(results.every(element => element));
            }
        );
    });

    describe('showCustomAttachment', function () {
        before(function () {
            cleanup();
        });

        it(
            'display the custom file attachment',
            function () {
                var results = [];
                $('body').html(
                    '<nav><div id="navbar"><ul><li id="attach" class="hidden ' +
                    'dropdown"><a href="#" class="dropdown-toggle" data-' +
                    'toggle="dropdown" role="button" aria-haspopup="true" ' +
                    'aria-expanded="false">Attach a file <span class="caret">' +
                    '</span></a><ul class="dropdown-menu"><li id="filewrap">' +
                    '<div><input type="file" id="file" name="file" /></div>' +
                    '</li><li id="customattachment" class="hidden"></li><li>' +
                    '<a id="fileremovebutton"  href="#">Remove attachment</a>' +
                    '</li></ul></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    $('#customattachment').hasClass('hidden')
                );
                $.PrivateBin.TopNav.showCustomAttachment();
                results.push(
                    !$('#customattachment').hasClass('hidden')
                );
                cleanup();
                assert.ok(results.every(element => element));
            }
        );
    });

    describe('collapseBar', function () {
        before(function () {
            cleanup();
        });

        it(
            'collapses the navigation when displayed on a small screen',
            function () {
                var clean = jsdom(),
                    results = [];
                $('body').html(
                    '<nav><div class="navbar-header"><button type="button" ' +
                    'class="navbar-toggle collapsed" data-toggle="collapse" ' +
                    'data-target="#navbar" aria-expanded="false" aria-controls' +
                    '="navbar">Toggle navigation</button><a class="reloadlink ' +
                    'navbar-brand" href=""><img alt="PrivateBin" ' +
                    'src="img/icon.svg" width="38" /></a></div><div ' +
                    'id="navbar"><ul><li><button id="newbutton" type=' +
                    '"button" class="hidden">New</button></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    $('.navbar-toggle').hasClass('collapsed') &&
                    $('#navbar').attr('aria-expanded') != 'true'
                );
                $.PrivateBin.TopNav.collapseBar();
                results.push(
                    $('.navbar-toggle').hasClass('collapsed') &&
                    $('#navbar').attr('aria-expanded') != 'true'
                );
                /*
                with the upgrade for bootstrap-3.3.7.js to bootstrap-3.4.1.js
                the mobile interface detection changed to check if the
                ontouchstart event exists, which broke this section of the test
                $('.navbar-toggle').trigger('click');
                results.push(
                    !$('.navbar-toggle').hasClass('collapsed') &&
                    $('#navbar').attr('aria-expanded') == 'true'
                );
                $.PrivateBin.TopNav.collapseBar();
                results.push(
                    $('.navbar-toggle').hasClass('collapsed') &&
                    $('#navbar').attr('aria-expanded') == 'false'
                );
                */
                clean();
                assert.ok(results.every(element => element));
            }
        );
    });

    describe('resetInput', function () {
        before(function () {
            cleanup();
        });

        it(
            'reset inputs to defaults (options off)',
            function () {
                var results = [];
                $('body').html(
                    '<nav><div id="navbar"><ul><li id="burnafterreadingoption" ' +
                    'class="hidden"><label><input type="checkbox" ' +
                    'id="burnafterreading" name="burnafterreading" /> ' +
                    'Burn after reading</label></li><li id="opendiscussionoption" ' +
                    'class="hidden"><label><input type="checkbox" ' +
                    'id="opendiscussion" name="opendiscussion" /> ' +
                    'Open discussion</label></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    !$.PrivateBin.TopNav.getBurnAfterReading()
                );
                results.push(
                    !$.PrivateBin.TopNav.getOpenDiscussion()
                );
                $('#burnafterreading').attr('checked', 'checked');
                $('#opendiscussion').attr('checked', 'checked');
                results.push(
                    $.PrivateBin.TopNav.getBurnAfterReading()
                );
                results.push(
                    $.PrivateBin.TopNav.getOpenDiscussion()
                );
                $.PrivateBin.TopNav.resetInput();
                results.push(
                    !$.PrivateBin.TopNav.getBurnAfterReading()
                );
                results.push(
                    !$.PrivateBin.TopNav.getOpenDiscussion()
                );
                cleanup();
                assert.ok(results.every(element => element));
            }
        );

        it(
            'reset inputs to defaults (burnafterreading on)',
            function () {
                var results = [];
                $('body').html(
                    '<nav><div id="navbar"><ul><li id="burnafterreadingoption" ' +
                    'class="hidden"><label><input type="checkbox" ' +
                    'id="burnafterreading" name="burnafterreading" checked="checked" /> ' +
                    'Burn after reading</label></li><li id="opendiscussionoption" ' +
                    'class="hidden"><label><input type="checkbox" ' +
                    'id="opendiscussion" name="opendiscussion" checked="checked" /> ' +
                    'Open discussion</label></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    $.PrivateBin.TopNav.getBurnAfterReading()
                );
                results.push(
                    !$.PrivateBin.TopNav.getOpenDiscussion()
                );
                $('#burnafterreading').removeAttr('checked');
                results.push(
                    !$.PrivateBin.TopNav.getBurnAfterReading()
                );
                results.push(
                    !$.PrivateBin.TopNav.getOpenDiscussion()
                );
                $.PrivateBin.TopNav.resetInput();
                results.push(
                    $.PrivateBin.TopNav.getBurnAfterReading()
                );
                results.push(
                    !$.PrivateBin.TopNav.getOpenDiscussion()
                );
                cleanup();
                assert.ok(results.every(element => element));
            }
        );

        it(
            'reset inputs to defaults (opendiscussion on)',
            function () {
                var results = [];
                $('body').html(
                    '<nav><div id="navbar"><ul><li id="burnafterreadingoption" ' +
                    'class="hidden"><label><input type="checkbox" ' +
                    'id="burnafterreading" name="burnafterreading" /> ' +
                    'Burn after reading</label></li><li id="opendiscussionoption" ' +
                    'class="hidden"><label><input type="checkbox" ' +
                    'id="opendiscussion" name="opendiscussion" checked="checked" /> ' +
                    'Open discussion</label></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    !$.PrivateBin.TopNav.getBurnAfterReading()
                );
                results.push(
                    $.PrivateBin.TopNav.getOpenDiscussion()
                );
                $('#opendiscussion').removeAttr('checked');
                $('#burnafterreading').prop('checked', true);
                results.push(
                    $.PrivateBin.TopNav.getBurnAfterReading()
                );
                results.push(
                    !$.PrivateBin.TopNav.getOpenDiscussion()
                );
                $.PrivateBin.TopNav.resetInput();
                results.push(
                    !$.PrivateBin.TopNav.getBurnAfterReading()
                );
                results.push(
                    $.PrivateBin.TopNav.getOpenDiscussion()
                );
                cleanup();
                assert.ok(results.every(element => element));
            }
        );
    });

    describe('getExpiration', function () {
        before(function () {
            cleanup();
        });

        it(
            'returns the currently selected expiration date',
            function () {
                $.PrivateBin.TopNav.init();
                assert.ok($.PrivateBin.TopNav.getExpiration() === null);
            }
        );
    });

    describe('getFileList', function () {
        before(function () {
            cleanup();
        });

        var File = window.File,
            FileList = window.FileList,
            path = require('path'),
            mime = require('mime-types');

        // mocking file input as per https://github.com/jsdom/jsdom/issues/1272
        function createFile(file_path) {
            var file = fs.statSync(file_path),
                lastModified = file.mtimeMs,
                size = file.size;

            return new File(
                [new fs.readFileSync(file_path)],
                path.basename(file_path),
                {
                    lastModified,
                    type: mime.lookup(file_path) || '',
                }
            )
        }

        function addFileList(input, file_paths) {
            if (typeof file_paths === 'string')
                file_paths = [file_paths]
            else if (!Array.isArray(file_paths)) {
                throw new Error('file_paths needs to be a file path string or an Array of file path strings')
            }

            const file_list = file_paths.map(fp => createFile(fp))
            file_list.__proto__ = Object.create(FileList.prototype)

            Object.defineProperty(input, 'files', {
                value: file_list,
                writeable: false,
            })

            return input
        }

        it(
            'returns the selected files',
            function () {
                var results = [];
                $('body').html(
                    '<nav><div id="navbar"><ul><li id="attach" class="hidden ' +
                    'dropdown"><a href="#" class="dropdown-toggle" data-' +
                    'toggle="dropdown" role="button" aria-haspopup="true" ' +
                    'aria-expanded="false">Attach a file <span class="caret">' +
                    '</span></a><ul class="dropdown-menu"><li id="filewrap">' +
                    '<div><input type="file" id="file" name="file" /></div>' +
                    '</li><li id="customattachment" class="hidden"></li><li>' +
                    '<a id="fileremovebutton"  href="#">Remove attachment</a>' +
                    '</li></ul></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    $.PrivateBin.TopNav.getFileList() === null
                );
                addFileList($('#file')[0], [
                    '../img/logo.svg',
                    '../img/busy.gif'
                ]);
                var files = $.PrivateBin.TopNav.getFileList();
                results.push(
                    files[0].name === 'logo.svg' &&
                    files[1].name === 'busy.gif'
                );
                cleanup();
                assert.ok(results.every(element => element));
            }
        );
    });

    describe('getBurnAfterReading', function () {
        before(function () {
            cleanup();
        });

        it(
            'returns if the burn-after-reading checkbox was ticked',
            function () {
                var results = [];
                $('body').html(
                    '<nav><div id="navbar"><ul><li id="burnafterreadingoption" ' +
                    'class="hidden"><label><input type="checkbox" ' +
                    'id="burnafterreading" name="burnafterreading" /> ' +
                    'Burn after reading</label></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    !$.PrivateBin.TopNav.getBurnAfterReading()
                );
                $('#burnafterreading').attr('checked', 'checked');
                results.push(
                    $.PrivateBin.TopNav.getBurnAfterReading()
                );
                $('#burnafterreading').removeAttr('checked');
                results.push(
                    !$.PrivateBin.TopNav.getBurnAfterReading()
                );
                cleanup();
                assert.ok(results.every(element => element));
            }
        );
    });

    describe('getOpenDiscussion', function () {
        before(function () {
            cleanup();
        });

        it(
            'returns if the open-discussion checkbox was ticked',
            function () {
                var results = [];
                $('body').html(
                    '<nav><div id="navbar"><ul><li id="opendiscussionoption" ' +
                    'class="hidden"><label><input type="checkbox" ' +
                    'id="opendiscussion" name="opendiscussion" /> ' +
                    'Open discussion</label></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    !$.PrivateBin.TopNav.getOpenDiscussion()
                );
                $('#opendiscussion').attr('checked', 'checked');
                results.push(
                    $.PrivateBin.TopNav.getOpenDiscussion()
                );
                $('#opendiscussion').removeAttr('checked');
                results.push(
                    !$.PrivateBin.TopNav.getOpenDiscussion()
                );
                cleanup();
                assert.ok(results.every(element => element));
            }
        );
    });


    describe('getPassword', function () {
        before(function () {
            cleanup();
        });

        jsc.property(
            'returns the contents of the password input',
            'string',
            function (password) {
                password = password.replace(/\r+/g, '');
                var results = [];
                $('body').html(
                    '<nav><div id="navbar"><ul><li><div id="password" ' +
                    'class="navbar-form hidden"><input type="password" ' +
                    'id="passwordinput" placeholder="Password (recommended)" ' +
                    'class="form-control" size="23" /></div></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    $.PrivateBin.TopNav.getPassword() === ''
                );
                $('#passwordinput').val(password);
                results.push(
                    $.PrivateBin.TopNav.getPassword() === password
                );
                $('#passwordinput').val('');
                results.push(
                    $.PrivateBin.TopNav.getPassword() === ''
                );
                cleanup();
                return results.every(element => element);
            }
        );
    });

    describe('getCustomAttachment', function () {
        before(function () {
            cleanup();
        });

        it(
            'returns the custom attachment element',
            function () {
                var results = [];
                $('body').html(
                    '<nav><div id="navbar"><ul><li id="attach" class="hidden ' +
                    'dropdown"><a href="#" class="dropdown-toggle" data-' +
                    'toggle="dropdown" role="button" aria-haspopup="true" ' +
                    'aria-expanded="false">Attach a file <span class="caret">' +
                    '</span></a><ul class="dropdown-menu"><li id="filewrap">' +
                    '<div><input type="file" id="file" name="file" /></div>' +
                    '</li><li id="customattachment" class="hidden"></li><li>' +
                    '<a id="fileremovebutton"  href="#">Remove attachment</a>' +
                    '</li></ul></li></ul></div></nav>'
                );
                $.PrivateBin.TopNav.init();
                results.push(
                    !$.PrivateBin.TopNav.getCustomAttachment().hasClass('test')
                );
                $('#customattachment').addClass('test');
                results.push(
                    $.PrivateBin.TopNav.getCustomAttachment().hasClass('test')
                );
                cleanup();
                assert.ok(results.every(element => element));
            }
        );
    });
});