dbmedialab/reader-critics

View on GitHub
src/test/database/persisting-services/WebsiteServiceTests.ts

Summary

Maintainability
A
0 mins
Test Coverage
//
// LESERKRITIKK v2 (aka Reader Critics)
// Copyright (C) 2017 DB Medialab/Aller Media AS, Oslo, Norway
// https://github.com/dbmedialab/reader-critics/
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation, either version 3 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <http://www.gnu.org/licenses/>.
//

import * as Promise from 'bluebird';

import * as path from 'path';

import { assert } from 'chai';
import { ISuiteCallbackContext } from 'mocha';

import ArticleURL from 'base/ArticleURL';
import Website from 'base/Website';

import { defaultLimit } from 'app/services/BasicPersistingService';
import { websiteService } from 'app/services';
import { EmptyError } from 'app/util/errors';

import * as app from 'app/util/applib';

const demoSites = path.join('resources', 'website', 'demo-sites.json5');

// Main test function

export default function(this: ISuiteCallbackContext) {
    this.slow(250);

    testParameterChecks();
    testClear();
    testSave();
    testCount();

    testGet();
    testGetRange();

    testIdentify();
}

// Test runtime data

let websiteCount : number;

// Check for thrown exceptions

const testParameterChecks = () => it('parameter checks', () => {
    assert.throws(() => websiteService.get(null), EmptyError);
    assert.throws(() => websiteService.identify(null), EmptyError);
    assert.throws(() => websiteService.save(null), EmptyError);
});

// websiteService.clear()

const testClear = () => it('clear()', () => websiteService.clear());

// websiteService.save()

const testSave = () => it('save()', () => app.loadJSON(demoSites).then(data => {
    assert.isArray(data);
    websiteCount = data.length;

    return Promise.mapSeries(data, websiteService.save);
})
.then(results => {
    assert.isArray(results);
    assert.lengthOf(results, websiteCount, 'Number of saved objects does not match');
}));

// websiteService.count()

const testCount = () => it('count()', () => websiteService.count()
.then(count => {
    assert.strictEqual(count, websiteCount);
}));

// websiteService.get()

const testGet = () => it('get()', () => {
    return Promise.all([
        websiteService.get('dagbladet.no'),
        websiteService.get('something-else.xyz'),
    ])
    .then((results : Website[]) => {
        assertWebsiteObject(results[0], 'dagbladet.no');
        assert.isNull(results[1]);
    });
});

// websiteService.getRange()

const testGetRange = () => it('getRange()', () => {
    const testLimit = 2;

    return Promise.all([
        // #1 should return the lesser of "defaultLimit" or "websiteCount" number of items:
        websiteService.getRange(),
        // #2 should return exactly "testLimit" items:
        websiteService.getRange(0, testLimit),
        // #3 skipping past the number of stored items should yield an empty result:
        websiteService.getRange(websiteCount),
    ])
    .spread((...ranges : Website[][]) => {
        ranges.forEach(result => {
            assert.isArray(result);
            result.forEach(item => assertWebsiteObject(item));
        });

        const lengthCheck = [
            Math.min(websiteCount, defaultLimit),
            testLimit,
            0,
        ];

        ranges.forEach((result : Website[], index : number) => {
            assert.lengthOf(
                result,
                lengthCheck[index],
                `Incorrect number of objects in test range #${index + 1}`
            );
        });
    });
});

// websiteService.identify()

const testIdentify = () => it('identify()', () => {
    const a : ArticleURL = new ArticleURL('http://www.dagbladet.no/mat/67728317');
    const b : ArticleURL = new ArticleURL('http://something-else.xyz/goes/nowhere');

    return Promise.all([
        websiteService.identify(a),
        websiteService.identify(b),
    ])
    .then((results : Website[]) => {
        assertWebsiteObject(results[0], 'dagbladet.no');
        assert.isNull(results[1]);
    });
});

// Generic structure check

const assertWebsiteObject = (w : Website, name? : string) => {
    assert.isObject(w);

    [ 'name', 'hosts', 'chiefEditors' ].forEach(prop => {
        assert.property(w, prop);
    });

    assert.isArray(w.hosts);
    assert.isArray(w.chiefEditors);

    if (name) {
        assert.strictEqual(w.name, name);
    }
};