<commit_before>import * as data from 'data';
import * as requester_JSON from 'json-requester';

const USERNAME_LOCAL_STORAGE_KEY = 'signed-in-user-username',
    AUTH_KEY_LOCAL_STORAGE_KEY = 'signed-in-user-auth-key',
    MAX_TICKET_PER_PAGE = 5,
    NUMBER_PER_PAGE_HEADER = 'number-per-page';

const clearLocalStorage = () => {
    localStorage.removeItem(USERNAME_LOCAL_STORAGE_KEY);
    localStorage.removeItem(AUTH_KEY_LOCAL_STORAGE_KEY);
};

describe('Data Layer Tests', () => {
    beforeEach(clearLocalStorage);
    afterEach(clearLocalStorage);
    describe('User Tests', () => {
        describe('isLoggedIn Tests', () => {
            it('Expect isLoggedIn() to return false when AUTH_KEY_LOCAL_STORAGE_KEY is not stored on localhost',
                () => {
                    expect(data.isLoggedIn()).to.be.false;
                });
            it('Expect isLoggedIn() to return true when AUTH_KEY_LOCAL_STORAGE_KEY is stored on localhost',
                () => {
                    localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, "valid auth key");
                    expect(data.isLoggedIn()).to.be.true;
                });
        });

        describe('getLoggedInUser Tests', () => {

            it('Expect getLoggedInUser() to return unknown when non user is logged in',
                () => {
                    //  const isLoggedInStub = sinon.stub(data, 'isLoggedIn').returns(false);
                    expect(data.getLoggedInUser()).to.be.equal('unknown');
                    //  isLoggedInStub.restore();
                });
            it('Expect getLoggedInUser() to return the username when user is logged in',
                () => {
                    //  const isLoggedInStub = sinon.stub(data, 'isLoggedIn').returns(true);
                    localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, 'valid-auth-key');
                    localStorage.setItem(USERNAME_LOCAL_STORAGE_KEY, 'validuser');

                    expect(data.getLoggedInUser()).to.be.equal('validuser');
                    //  isLoggedInStub.restore();
                });
        });
    });
    describe('Tickets tests', () => {
        describe('getTicket tests', () => {
            it('Expect getTicket to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicket('1');
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicket to make get request to api/ticket', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicket('1');
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/ticket');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicket to make get request with headers ticket', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicket('1');
                expect(jsonRequesterGetStub.args[0][1].headers.ticket).to.be.equal('1');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicket to make get request with headers ticket', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, 'valid-auth-key');
                data.getTicket('1');
                expect(jsonRequesterGetStub.args[0][1].headers['x-auth-key']).to.be.equal('valid-auth-key');
                jsonRequesterGetStub.restore();
            });
        });
        describe('getTicketsCount tests', () => {
            it('Expect getTicketsCount to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount();
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsCount to make get request to api/ticketsCount', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount();
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/ticketsCount');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsCount to return totalTicketsLength in result property', (done) => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount().then((res) => {
                        expect(res.result).to.be.equal(response.totalTicketsLength);
                    })
                    .then(done, done);
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsCount to return maxTicketsPerPage in result property', (done) => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount().then((res) => {
                        expect(res.maxTicketsPerPage).to.be.equal(MAX_TICKET_PER_PAGE);
                    })
                    .then(done, done);
                jsonRequesterGetStub.restore();
            });
        });
        describe('getTicketsRange tests', () => {
            it('Expect getTicketsRange to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                jsonRequesterGetStub.returns(Promise.resolve());
                data.getTicketsRange();
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request to api/tickets', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                jsonRequesterGetStub.returns(Promise.resolve());
                data.getTicketsRange();
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/tickets');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request with headers number-per-page', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicketsRange({});
                expect(jsonRequesterGetStub.args[0][1].headers[NUMBER_PER_PAGE_HEADER]).to.be.equal(MAX_TICKET_PER_PAGE);
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request with headers passed as parameter', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const queryParams = {
                    page: 1,
                    engineer: 1
                };
                data.getTicketsRange(queryParams);
                for (const key in queryParams) {
                    expect(jsonRequesterGetStub.args[0][1].headers[key]).to.be.equal(queryParams[key]);
                };
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request with headers startDate when date is passed as parameter', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const queryParams = {
                    date: 1
                };
                data.getTicketsRange(queryParams);
                expect(jsonRequesterGetStub.args[0][1].headers['startDate']).to.be.equal(queryParams['date']);
                jsonRequesterGetStub.restore();
            });
        });
        describe('updateTicket Tests', () => {
            it('Expect updateTicket to call json requester put', () => {
                const jsonRequesterPUTStub = sinon.stub(requester_JSON, 'put');
                jsonRequesterPUTStub.returns(Promise.resolve());
                data.updateTicket();
                expect(jsonRequesterPUTStub).to.have.been.calledOnce;
                jsonRequesterPUTStub.restore();
            });
            it('Expect updateTicket to make put request to api/updateTicket', () => {
                const jsonRequesterPUTStub = sinon.stub(requester_JSON, 'put');
                jsonRequesterPUTStub.returns(Promise.resolve());
                data.updateTicket();
                expect(jsonRequesterPUTStub).to.have.been.calledWith('api/updateTicket');
                jsonRequesterPUTStub.restore();
            });
            it('Expect updateTicket to make put request with headers x-auth-key', () => {
                const jsonRequesterPUTStub = sinon.stub(requester_JSON, 'put');
                jsonRequesterPUTStub.returns(Promise.resolve());
                localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, 'valid-auth-key');
                data.updateTicket();
                expect(jsonRequesterPUTStub.args[0][1].headers['x-auth-key']).to.be.equal('valid-auth-key');
                jsonRequesterPUTStub.restore();
            });
            it('Expect updateTicket to make put request with data passed as parameter', () => {
                const jsonRequesterPUTStub = sinon.stub(requester_JSON, 'put');
                jsonRequesterPUTStub.returns(Promise.resolve());
                localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, 'valid-auth-key');
                const ticket = {
                    id: 10
                };
                data.updateTicket(ticket);
                expect(jsonRequesterPUTStub.args[0][1].data).to.be.equal(ticket);
                jsonRequesterPUTStub.restore();
            });
            it('Expect updateTicket to return ticket in result property', (done) => {
                const jsonRequesterPUTStub = sinon.stub(requester_JSON, 'put');
                const response = {
                    result: "put-result"
                };
                jsonRequesterPUTStub.returns(Promise.resolve(response));
                data.updateTicket().then((res) => {
                        expect(res.result).to.be.equal(response.result);
                    })
                    .then(done, done);
                jsonRequesterPUTStub.restore();
            });
        });
    });
    describe('Utils Tests', () => {
        describe('getPopoverValue Tests', () => {
            it('Expect getPopoverValue to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getPopoverValue('1');
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getPopoverValue to make get request to api/popover', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getPopoverValue('1');
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/popover');
                jsonRequesterGetStub.restore();
            });
            it('Expect getPopoverValue to make get request with headers inputValue', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getPopoverValue('48');
                expect(jsonRequesterGetStub.args[0][1].headers.inputValue).to.be.equal('48');
                jsonRequesterGetStub.restore();
            });
        });
        describe('splitQueryParameters Tests', () => {
            it('Expect splitQueryParameters to return empty object when no parameters are passed', () => {
                expect(data.splitQueryParameters()).to.be.deep.equal({});
            });
            it('Expect splitQueryParameters to return empty object when empty string is passed', () => {
                expect(data.splitQueryParameters("")).to.be.deep.equal({});
            });
            it('Expect splitQueryParameters to return splited parameters in object when valid query string is passed', () => {
                const expected = {
                    page: '1',
                    engineer: '1'
                };
                expect(data.splitQueryParameters("page=1&engineer=1")).to.be.deep.equal(expected);
            });
        });
    });
});

mocha.run();
<commit_msg>add sendNewTicket tests<commit_after>import * as data from 'data';
import * as requester_JSON from 'json-requester';

const USERNAME_LOCAL_STORAGE_KEY = 'signed-in-user-username',
    AUTH_KEY_LOCAL_STORAGE_KEY = 'signed-in-user-auth-key',
    MAX_TICKET_PER_PAGE = 5,
    NUMBER_PER_PAGE_HEADER = 'number-per-page';

const clearLocalStorage = () => {
    localStorage.removeItem(USERNAME_LOCAL_STORAGE_KEY);
    localStorage.removeItem(AUTH_KEY_LOCAL_STORAGE_KEY);
};

describe('Data Layer Tests', () => {
    beforeEach(clearLocalStorage);
    afterEach(clearLocalStorage);
    describe('User Tests', () => {
        describe('isLoggedIn Tests', () => {
            it('Expect isLoggedIn() to return false when AUTH_KEY_LOCAL_STORAGE_KEY is not stored on localhost',
                () => {
                    expect(data.isLoggedIn()).to.be.false;
                });
            it('Expect isLoggedIn() to return true when AUTH_KEY_LOCAL_STORAGE_KEY is stored on localhost',
                () => {
                    localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, "valid auth key");
                    expect(data.isLoggedIn()).to.be.true;
                });
        });

        describe('getLoggedInUser Tests', () => {

            it('Expect getLoggedInUser() to return unknown when non user is logged in',
                () => {
                    //  const isLoggedInStub = sinon.stub(data, 'isLoggedIn').returns(false);
                    expect(data.getLoggedInUser()).to.be.equal('unknown');
                    //  isLoggedInStub.restore();
                });
            it('Expect getLoggedInUser() to return the username when user is logged in',
                () => {
                    //  const isLoggedInStub = sinon.stub(data, 'isLoggedIn').returns(true);
                    localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, 'valid-auth-key');
                    localStorage.setItem(USERNAME_LOCAL_STORAGE_KEY, 'validuser');

                    expect(data.getLoggedInUser()).to.be.equal('validuser');
                    //  isLoggedInStub.restore();
                });
        });
    });
    describe('Tickets tests', () => {
        describe('getTicket tests', () => {
            it('Expect getTicket to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicket('1');
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicket to make get request to api/ticket', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicket('1');
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/ticket');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicket to make get request with headers ticket', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicket('1');
                expect(jsonRequesterGetStub.args[0][1].headers.ticket).to.be.equal('1');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicket to make get request with headers ticket', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, 'valid-auth-key');
                data.getTicket('1');
                expect(jsonRequesterGetStub.args[0][1].headers['x-auth-key']).to.be.equal('valid-auth-key');
                jsonRequesterGetStub.restore();
            });
        });
        describe('getTicketsCount tests', () => {
            it('Expect getTicketsCount to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount();
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsCount to make get request to api/ticketsCount', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount();
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/ticketsCount');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsCount to return totalTicketsLength in result property', (done) => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount().then((res) => {
                        expect(res.result).to.be.equal(response.totalTicketsLength);
                    })
                    .then(done, done);
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsCount to return maxTicketsPerPage in result property', (done) => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount().then((res) => {
                        expect(res.maxTicketsPerPage).to.be.equal(MAX_TICKET_PER_PAGE);
                    })
                    .then(done, done);
                jsonRequesterGetStub.restore();
            });
        });
        describe('getTicketsRange tests', () => {
            it('Expect getTicketsRange to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                jsonRequesterGetStub.returns(Promise.resolve());
                data.getTicketsRange();
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request to api/tickets', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                jsonRequesterGetStub.returns(Promise.resolve());
                data.getTicketsRange();
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/tickets');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request with headers number-per-page', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicketsRange({});
                expect(jsonRequesterGetStub.args[0][1].headers[NUMBER_PER_PAGE_HEADER]).to.be.equal(MAX_TICKET_PER_PAGE);
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request with headers passed as parameter', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const queryParams = {
                    page: 1,
                    engineer: 1
                };
                data.getTicketsRange(queryParams);
                for (const key in queryParams) {
                    expect(jsonRequesterGetStub.args[0][1].headers[key]).to.be.equal(queryParams[key]);
                };
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request with headers startDate when date is passed as parameter', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const queryParams = {
                    date: 1
                };
                data.getTicketsRange(queryParams);
                expect(jsonRequesterGetStub.args[0][1].headers['startDate']).to.be.equal(queryParams['date']);
                jsonRequesterGetStub.restore();
            });
        });
        describe('updateTicket Tests', () => {
            it('Expect updateTicket to call json requester put', () => {
                const jsonRequesterPUTStub = sinon.stub(requester_JSON, 'put');
                jsonRequesterPUTStub.returns(Promise.resolve());
                data.updateTicket();
                expect(jsonRequesterPUTStub).to.have.been.calledOnce;
                jsonRequesterPUTStub.restore();
            });
            it('Expect updateTicket to make put request to api/updateTicket', () => {
                const jsonRequesterPUTStub = sinon.stub(requester_JSON, 'put');
                jsonRequesterPUTStub.returns(Promise.resolve());
                data.updateTicket();
                expect(jsonRequesterPUTStub).to.have.been.calledWith('api/updateTicket');
                jsonRequesterPUTStub.restore();
            });
            it('Expect updateTicket to make put request with headers x-auth-key', () => {
                const jsonRequesterPUTStub = sinon.stub(requester_JSON, 'put');
                jsonRequesterPUTStub.returns(Promise.resolve());
                localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, 'valid-auth-key');
                data.updateTicket();
                expect(jsonRequesterPUTStub.args[0][1].headers['x-auth-key']).to.be.equal('valid-auth-key');
                jsonRequesterPUTStub.restore();
            });
            it('Expect updateTicket to make put request with data passed as parameter', () => {
                const jsonRequesterPUTStub = sinon.stub(requester_JSON, 'put');
                jsonRequesterPUTStub.returns(Promise.resolve());
                localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, 'valid-auth-key');
                const ticket = {
                    id: 10
                };
                data.updateTicket(ticket);
                expect(jsonRequesterPUTStub.args[0][1].data).to.be.equal(ticket);
                jsonRequesterPUTStub.restore();
            });
            it('Expect updateTicket to return ticket in result property', (done) => {
                const jsonRequesterPUTStub = sinon.stub(requester_JSON, 'put');
                const response = {
                    result: "put-result"
                };
                jsonRequesterPUTStub.returns(Promise.resolve(response));
                data.updateTicket().then((res) => {
                        expect(res.result).to.be.equal(response.result);
                    })
                    .then(done, done);
                jsonRequesterPUTStub.restore();
            });
        });
        describe('sendNewTicket tests', () => {
            it('Expect sendNewTicket to call json requester post', () => {
                const jsonRequesterPOSTStub = sinon.stub(requester_JSON, 'post');
                jsonRequesterPOSTStub.returns(Promise.resolve());
                data.sendNewTicket();
                expect(jsonRequesterPOSTStub).to.have.been.calledOnce;
                jsonRequesterPOSTStub.restore();
            });
            it('Expect sendNewTicket to make post request to api/newticket', () => {
                const jsonRequesterPOSTStub = sinon.stub(requester_JSON, 'post');
                jsonRequesterPOSTStub.returns(Promise.resolve());
                data.sendNewTicket();
                expect(jsonRequesterPOSTStub).to.have.been.calledWith('api/newticket');
                jsonRequesterPOSTStub.restore();
            });
            it('Expect sendNewTicket to make post request with data passed as parameter', () => {
                const jsonRequesterPOSTStub = sinon.stub(requester_JSON, 'post');
                jsonRequesterPOSTStub.returns(Promise.resolve());
                const ticket = {
                    id: 10
                };
                data.sendNewTicket(ticket);
                expect(jsonRequesterPOSTStub.args[0][1].data).to.be.equal(ticket);
                jsonRequesterPOSTStub.restore();
            });
            it('Expect sendNewTicket to return result property in responce', (done) => {
                const jsonRequesterPOSTStub = sinon.stub(requester_JSON, 'post');
                const response = {
                    result: "post-result"
                };
                jsonRequesterPOSTStub.returns(Promise.resolve(response));
                data.sendNewTicket().then((res) => {
                        expect(res.result).to.be.equal(response.result);
                    })
                    .then(done, done);
                jsonRequesterPOSTStub.restore();
            });
        });
    });
    describe('Utils Tests', () => {
        describe('getPopoverValue Tests', () => {
            it('Expect getPopoverValue to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getPopoverValue('1');
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getPopoverValue to make get request to api/popover', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getPopoverValue('1');
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/popover');
                jsonRequesterGetStub.restore();
            });
            it('Expect getPopoverValue to make get request with headers inputValue', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getPopoverValue('48');
                expect(jsonRequesterGetStub.args[0][1].headers.inputValue).to.be.equal('48');
                jsonRequesterGetStub.restore();
            });
        });
        describe('splitQueryParameters Tests', () => {
            it('Expect splitQueryParameters to return empty object when no parameters are passed', () => {
                expect(data.splitQueryParameters()).to.be.deep.equal({});
            });
            it('Expect splitQueryParameters to return empty object when empty string is passed', () => {
                expect(data.splitQueryParameters("")).to.be.deep.equal({});
            });
            it('Expect splitQueryParameters to return splited parameters in object when valid query string is passed', () => {
                const expected = {
                    page: '1',
                    engineer: '1'
                };
                expect(data.splitQueryParameters("page=1&engineer=1")).to.be.deep.equal(expected);
            });
        });
    });
});

mocha.run();
<|endoftext|>


<commit_before>/* Copyright(c) 2018 Philip Mulcahy. */
/* jshint strict: true, esversion: 6 */

const date_tests = (() => {
    "use strict";

    const de_test = () => {
         return (
             date.normalizeDateString('29 Dezember 2017') == '2017-12-29' &&
             date.normalizeDateString('29. Dezember 2017') == '2017-12-29'
         );
    };

    const es_test = () => {
        return (
            date.normalizeDateString('16 de noviembre de 2018') == '2018-11-16' &&
            date.normalizeDateString('23 de agosto de 2016') == '2016-08-23'
        );
   };

    const fr_test = () => {
         return (
             date.normalizeDateString('29 mai 2018') == '2018-05-29' &&
             date.normalizeDateString('29. mai 2018') == '2018-05-29'
         );
    };

    const it_test = () => {
         return (
             date.normalizeDateString('22. luglio 2016') == '2016-07-22'
         );
    };

    const uk_test = () => {
         return (
             date.normalizeDateString('15 July 2018') == '2018-07-15' &&
             date.normalizeDateString('4 March 2018') == '2018-03-04'
         );
    };

    const us_test = () => {
         return (
             date.normalizeDateString('October 14, 2016') == '2016-10-14'
         );
    };

    return {
        de_test: de_test,
        es_test: es_test,
        fr_test: fr_test,
        it_test: it_test,
        uk_test: uk_test,
        us_test: us_test
    };
})()

tests.register('date', date_tests);
<commit_msg>removed a trailing space<commit_after>/* Copyright(c) 2018 Philip Mulcahy. */
/* jshint strict: true, esversion: 6 */

const date_tests = (() => {
    "use strict";

    const de_test = () => {
         return (
             date.normalizeDateString('29 Dezember 2017') == '2017-12-29' &&
             date.normalizeDateString('29. Dezember 2017') == '2017-12-29'
         );
    };

    const es_test = () => {
        return (
            date.normalizeDateString('16 de noviembre de 2018') == '2018-11-16' &&
            date.normalizeDateString('23 de agosto de 2016') == '2016-08-23'
        );
   };

    const fr_test = () => {
         return (
             date.normalizeDateString('29 mai 2018') == '2018-05-29' &&
             date.normalizeDateString('29. mai 2018') == '2018-05-29'
         );
    };

    const it_test = () => {
         return (
             date.normalizeDateString('22. luglio 2016') == '2016-07-22'
         );
    };

    const uk_test = () => {
         return (
             date.normalizeDateString('15 July 2018') == '2018-07-15' &&
             date.normalizeDateString('4 March 2018') == '2018-03-04'
         );
    };

    const us_test = () => {
         return (
             date.normalizeDateString('October 14, 2016') == '2016-10-14'
         );
    };

    return {
        de_test: de_test,
        es_test: es_test,
        fr_test: fr_test,
        it_test: it_test,
        uk_test: uk_test,
        us_test: us_test
    };
})()

tests.register('date', date_tests);
<|endoftext|>


<commit_before>/*
 * Routes initializer
 *
 * @module warepot/util/initRoutes
 */

'use strict'

// modules > 3rd party
const _ = require('lodash')

/*
 * Initializes an array of routes on an express instance
 *
 * @param {Object} express Express instance to set up routes on
 * @param {Array[]} routes Array of routes. Either just a function or array (`[ path, method, middleware ]`, or `[ path, metod, [ mw1, mw2 ] ]`)
 * @returns {undefined}
 */
module.exports = function initRoutes(express, routes) {
  _.each(routes, (route) => {
    if (_.isFunction(route)) {
      express.use(route)
    } else if (_.isArray(route)) {
      let [ path, method, ...middleware ] = route

      if (_.isEmpty(middleware))
        throw new Error('No middleware defined for [' + method + ']:' + path)

      middleware = middleware.map((mw) => {
        if (_.isArray(mw)) {
          return (req, res, next) => {
            next = _.after(mw.length, next)

            mw.forEach(mw => mw(req, res, next))
          }
        } else if (!_.isFunction(mw)) {
          throw new Error('Undefined or non-function middleware found [' + method + ']:' + path)
        }

        return mw
      })

      // use spread operator so it works with `express.param` (which only accepts
      // a single function, not an array of fncs)
      express[method](path, ...middleware)
    } else {
      throw new Error('Route is not an Array or Function.')
    }
  })
}
<commit_msg>Renamed parameter express > router, since one could pass a router instance as well<commit_after>/*
 * Routes initializer
 *
 * @module warepot/util/initRoutes
 */

'use strict'

// modules > 3rd party
const _ = require('lodash')

/*
 * Initializes an array of routes on an express instance
 *
 * @param {Object} router Router or Express instance to set up routes on
 * @param {Array[]} routes Array of routes. Either just a function or array (`[ path, method, middleware ]`, or `[ path, metod, [ mw1, mw2 ] ]`)
 * @returns {undefined}
 */
module.exports = function initRoutes(router, routes) {
  _.each(routes, (route) => {
    if (_.isFunction(route)) {
      router.use(route)
    } else if (_.isArray(route)) {
      let [ path, method, ...middleware ] = route

      if (_.isEmpty(middleware))
        throw new Error('No middleware defined for [' + method + ']:' + path)

      middleware = middleware.map((mw) => {
        if (_.isArray(mw)) {
          return (req, res, next) => {
            next = _.after(mw.length, next)

            mw.forEach(mw => mw(req, res, next))
          }
        } else if (!_.isFunction(mw)) {
          throw new Error('Undefined or non-function middleware found [' + method + ']:' + path)
        }

        return mw
      })

      // use spread operator so it works with `router.param` (which only accepts
      // a single function, not an array of fncs)
      router[method](path, ...middleware)
    } else {
      throw new Error('Route is not an Array or Function.')
    }
  })
}
<|endoftext|>


<commit_before>import { ObjectPool } from "lively.serializer2";
import { World } from "./index.js";
import { resource } from "lively.resources";
import { newMorphId } from "./morph.js";

function normalizeOptions(options) {
  options = {reinitializeIds: false, ...options}

  if (options.reinitializeIds)
    options.reinitializeIds = typeof options.reinitializeIds === "function" ?
      options.reinitializeIds :
      (id, ref) => ref.realObj.isMorph ? newMorphId(ref.realObj.constructor) : null;

  return options;
}

export function serializeMorph(m, options) {
  options = normalizeOptions(options);
  var objPool = options.objPool || new ObjectPool(options),
      ref = objPool.add(m);
  return {id: ref.id, snapshot: objPool.snapshot()};
}

export function deserializeMorph(idAndSnapshot, options) {
  options = normalizeOptions(options);
  var {id, snapshot} = idAndSnapshot,
      objPool = options.objPool || new ObjectPool(options);
  objPool.readSnapshot(snapshot);
  return objPool.resolveToObj(id)
}

export async function loadWorldFromResource(fromResource) {
  var data = JSON.parse(await fromResource.read());
  // load required modules
  await Promise.all(
    ObjectPool.requiredModulesOfSnapshot(data.snapshot)
      .map(modId =>
        (System.get(modId) ? null : System.import(modId))
                .catch(e => console.error(`Error loading ${modId}`, e))));

  return deserializeMorph(data);
}

export function saveWorldToResource(world = World.defaultWorld(), toResource) {

  if (!toResource) {
    var htmlResource = resource(document.location.href),
        name = htmlResource.name();
    toResource = htmlResource
      .join("../" + name.replace(/\.[^\.]+/, "-world.json"))
      .withRelativePartsResolved()
  }

  if (typeof toResource === "string")
    toResource = resource(toResource);

  // pretty printing bloats 2x!
  return toResource.write(JSON.stringify(serializeMorph(world), null, 2));
  // return toResource.write(JSON.stringify(serializeMorph(world)));
}

// await saveWorldToResource();

export function copyMorph(morph) {
  return deserializeMorph(serializeMorph(morph), {reinitializeIds: true});
}<commit_msg>using (de)serialize of serializer<commit_after>import { ObjectPool, serialize, deserialize } from "lively.serializer2";
import { World } from "./index.js";
import { resource } from "lively.resources";
import { newMorphId } from "./morph.js";

function normalizeOptions(options) {
  options = {reinitializeIds: false, ...options}

  if (options.reinitializeIds)
    options.reinitializeIds = typeof options.reinitializeIds === "function" ?
      options.reinitializeIds :
      (id, ref) => ref.realObj.isMorph ? newMorphId(ref.realObj.constructor) : null;

  return options;
}

export function serializeMorph(m, options) {
  return serialize(m, normalizeOptions(options));
}

export function deserializeMorph(idAndSnapshot, options) {
  return deserialize(idAndSnapshot, normalizeOptions(options));
}

export async function loadWorldFromResource(fromResource) {
  var data = JSON.parse(await fromResource.read());
  // load required modules
  await Promise.all(
    ObjectPool.requiredModulesOfSnapshot(data.snapshot)
      .map(modId =>
        (System.get(modId) ? null : System.import(modId))
                .catch(e => console.error(`Error loading ${modId}`, e))));

  return deserializeMorph(data);
}

export function saveWorldToResource(world = World.defaultWorld(), toResource) {

  if (!toResource) {
    var htmlResource = resource(document.location.href),
        name = htmlResource.name();
    toResource = htmlResource
      .join("../" + name.replace(/\.[^\.]+/, "-world.json"))
      .withRelativePartsResolved()
  }

  if (typeof toResource === "string")
    toResource = resource(toResource);

  // pretty printing bloats 2x!
  return toResource.write(JSON.stringify(serializeMorph(world), null, 2));
  // return toResource.write(JSON.stringify(serializeMorph(world)));
}

// await saveWorldToResource();

export function copyMorph(morph) {
  return deserializeMorph(serializeMorph(morph), {reinitializeIds: true});
}<|endoftext|>


<commit_before>/*@preserve Copyright (C) 2016 Crawford Currie http://c-dot.co.uk license MIT*/

const fs = require("fs");
const serialize = require("serialize-javascript");
const Url = require("url");

const Utils = require("../common/Utils.js");

const TAG = "Server";

var setup = {
    /**
     * Initialise the singleton server from the given configuration
     * @param {Config} config the configuration data
     */
    configure: function(config, controller) {
        "use strict";
        setup.controller = controller;
        setup.server = new Server(config);
    }
};
module.exports = setup;

/**
 * HTTP(S) server object (singleton).
 * @param {Config} config configuration object
 * @protected
 * @class
 */
function Server(config, controller) {
    "use strict";

    var self = this;
    self.config = config;

    var handler = function(request, response) {
        if (self[request.method]) {
            self[request.method].call(self, request, response);
        } else {
            response.statusCode = 405;
            response.write("No support for " + request.method);
            response.end();
        }
    };
    var httpot, https = config.get("ssl");
    if (typeof https !== "undefined") {
        var options = {};
        options.key = fs.readFileSync(Utils.expandEnvVars(https.key));
	console.TRACE(TAG, "Key " + https.key + " loaded");
        options.cert = fs.readFileSync(Utils.expandEnvVars(https.cert));
        console.TRACE(TAG, "Certificate " + https.cert + " loaded");
        console.TRACE(TAG, "HTTPS starting on port " + config.get("port")
                     + " with key " + https.key);

        httpot = require("https").createServer(options, handler);
    } else {
        console.TRACE(TAG, "HTTP starting on port " + config.get("port"));
        httpot = require("http").createServer(handler);
    }
    httpot.listen(config.get("port"));
}

/**
 * Common handling for requests, POST or GET
 * @private
 */
Server.prototype.handle = function(path, params, response) {
    "use strict";
    if (path.indexOf("/") !== 0 || path.length === 0)
        throw "Bad command";
    path = path.substring(1).split("/");
    var command = path.shift();
    if (typeof setup.controller === "undefined") {
        // Not ready
        response.statusCode = 500;
        response.end();
        return;
    }
    setup.controller.dispatch(
        command, path, params,
        function(reply) {
            response.writeHead(
                200, "OK",
                {
                    // Don't send as application/json; we
                    // don't want the receiver to parse it
                    "Content-Type": "text/plain",
                    "Access-Control-Allow-Origin": null,
                    "Access-Control-Allow-Methods": "POST,GET"
                });
            response.statusCode = 200;
            if (typeof reply !== "undefined" && reply !== null)
                response.write(serialize(reply));
            response.end();
        });
};

/**
 * AJAX request to get the status of the server, and set the position
 * of a device.
 * @private
 */
Server.prototype.GET = function(request, response) {
    "use strict";
    try {
        // Parse URL parameters and pass them as the data
        var req = Url.parse("" + request.url, true);
        this.handle(req.pathname, req.query, response);
    } catch (e) {
        console.TRACE(TAG, e + " in " + request.url + "\n" + e.stack);
        response.write(e + " in " + request.url + "\n");
        response.statusCode = 400;
    }
};

/**
 * AJAX request to set the status of the server.
 * @private
 */
Server.prototype.POST = function(request, response) {
    "use strict";

    var body = [], self = this;
    request.on("data", function(chunk) {
        body.push(chunk);
    }).on("end", function() {
        try {
            // Parse the JSON body and pass as the data
            var object;
            if (typeof body !== "undefined" && body !== "")
                object = JSON.parse(Buffer.concat(body).toString());
            self.handle(request.url, object, response);
        } catch (e) {
            console.TRACE(TAG, e + " in " + request.url + "\n" + e.stack);
            response.write(e + " in " + request.url + "\n");
            response.statusCode = 400;
        }
    });
};
<commit_msg>Monitor handling<commit_after>/*@preserve Copyright (C) 2016 Crawford Currie http://c-dot.co.uk license MIT*/

const fs = require("fs");
const serialize = require("serialize-javascript");
const Url = require("url");

const Utils = require("../common/Utils.js");

const TAG = "Server";

var setup = {
    /**
     * Initialise the singleton server from the given configuration
     * @param {Config} config the configuration data
     */
    configure: function(config, controller) {
        "use strict";
        setup.controller = controller;
        setup.server = new Server(config);
    }
};
module.exports = setup;

/**
 * HTTP(S) server object (singleton).
 * @param {Config} config configuration object
 * @protected
 * @class
 */
function Server(config, controller) {
    "use strict";

    var self = this;
    self.config = config;

    var handler = function(request, response) {
        if (self[request.method]) {
            self[request.method].call(self, request, response);
        } else {
            response.statusCode = 405;
            response.write("No support for " + request.method);
            response.end();
        }
    };
    var httpot, https = config.get("ssl");
    if (typeof https !== "undefined") {
        var options = {};
        options.key = fs.readFileSync(Utils.expandEnvVars(https.key));
	console.TRACE(TAG, "Key " + https.key + " loaded");
        options.cert = fs.readFileSync(Utils.expandEnvVars(https.cert));
        console.TRACE(TAG, "Certificate " + https.cert + " loaded");
        console.TRACE(TAG, "HTTPS starting on port " + config.get("port")
                     + " with key " + https.key);

        httpot = require("https").createServer(options, handler);
    } else {
        console.TRACE(TAG, "HTTP starting on port " + config.get("port"));
        httpot = require("http").createServer(handler);
    }
    httpot.listen(config.get("port"));
}

/**
 * Common handling for requests, POST or GET
 * @private
 */
Server.prototype.handle = function(path, params, response) {
    "use strict";
    if (path.indexOf("/") !== 0 || path.length === 0)
        throw "Bad command";
    path = path.substring(1).split("/");
    var command = path.shift();

    console.TRACE(TAG, "Handling " + command);
    if (typeof setup.controller === "undefined") {
        // Not ready
        response.statusCode = 500;
        response.end();
        return;
    }
    setup.controller.dispatch(
        command, path, params,
        function(reply) {
            response.writeHead(
                200, "OK",
                {
                    // Don't send as application/json; we
                    // don't want the receiver to parse it
                    "Content-Type": "text/plain",
                    "Access-Control-Allow-Origin": null,
                    "Access-Control-Allow-Methods": "POST,GET"
                });
            response.statusCode = 200;
            if (typeof reply !== "undefined" && reply !== null)
                response.write(serialize(reply));
            response.end();
	    console.TRACE(TAG, "Handled " + command);
        });
};

/**
 * AJAX request to get the status of the server, and set the position
 * of a device.
 * @private
 */
Server.prototype.GET = function(request, response) {
    "use strict";
    try {
        // Parse URL parameters and pass them as the data
        var req = Url.parse("" + request.url, true);
        this.handle(req.pathname, req.query, response);
    } catch (e) {
        console.TRACE(TAG, e + " in " + request.url + "\n" + e.stack);
        response.write(e + " in " + request.url + "\n");
        response.statusCode = 400;
    }
};

/**
 * AJAX request to set the status of the server.
 * @private
 */
Server.prototype.POST = function(request, response) {
    "use strict";

    var body = [], self = this;
    request.on("data", function(chunk) {
        body.push(chunk);
    }).on("end", function() {
        try {
            // Parse the JSON body and pass as the data
            var object;
            if (typeof body !== "undefined" && body !== "")
                object = JSON.parse(Buffer.concat(body).toString());
            self.handle(request.url, object, response);
        } catch (e) {
            console.TRACE(TAG, e + " in " + request.url + "\n" + e.stack);
            response.write(e + " in " + request.url + "\n");
            response.statusCode = 400;
        }
    });
};
<|endoftext|>


<commit_before>'use strict'
const log = require('./log')
const querystring = require('querystring')
const rp = require('request-promise')
const settings = require('./configuration').server
const CanvasApi = require('kth-canvas-api')
const csv = require('./csvFile')
const ldap = require('./ldap')
const _ = require('lodash')
const canvasApiUrl = `https://${settings.canvas.host}/api/v1`

function exportResults (req, res) {
  try {
    let b = req.body
    log.info(`The user ${b.lis_person_sourcedid}, ${b.custom_canvas_user_login_id}, is exporting the course ${b.context_label} with id ${b.custom_canvas_course_id}`)
    let courseRound = b.lis_course_offering_sourcedid
    const canvasCourseId = b.custom_canvas_course_id
    const fullUrl = (settings.proxyBase || (req.protocol + '://' + req.get('host'))) + req.originalUrl
    const nextUrl = fullUrl + '2?' + querystring.stringify({courseRound, canvasCourseId})
    log.info('Tell auth to redirect back to', nextUrl)
    log.info('using canvas client id', settings.canvas.clientId)
    const basicUrl = `https://${settings.canvas.host}/login/oauth2/auth?` + querystring.stringify({client_id: settings.canvas.clientId, response_type: 'code', redirect_uri: nextUrl})
    res.redirect(basicUrl)
  } catch (e) {
    log.error('Export failed:', e)
    res.status(500).send('Trasigt')
  }
}

async function getAccessToken ({clientId, clientSecret, redirectUri, code}) {
  const auth = await rp({
    method: 'POST',
    uri: `https://${settings.canvas.host}/login/oauth2/token`,
    body: {
      grant_type: 'authorization_code',
      client_id: clientId,
      client_secret: clientSecret,
      redirect_uri: redirectUri,
      code
    },
    json: true
  })
  return auth.access_token
}

async function getAssignmentIdsAndHeaders ({canvasApi, canvasCourseId}) {
  const assignmentIds = []
  const headers = {}

  const assignments = await canvasApi.recursePages(`${canvasApiUrl}/courses/${canvasCourseId}/assignments`)

  for (let t of assignments) {
    const id = '' + t.id
    assignmentIds.push(id)
    headers[id] = `${t.name} (${t.id})`
  }
  return {assignmentIds, headers}
}

async function createFixedColumnsContent ({student, ldapClient, section, canvasUser}) {
  let row
  try {
    const ugUser = await ldap.lookupUser(ldapClient, student.sis_user_id)
    row = {
      kthid: student.sis_user_id,
      givenName: ugUser.givenName,
      surname: ugUser.sn,
      personnummer: ugUser.norEduPersonNIN
    }
  } catch (err) {
    log.error('An error occured while trying to find user in ldap:', err)
    log.info('No user from ldap, use empty row instead')
    row = {}
  }

  return [
    student.sis_user_id || '',
    student.user_id || '',
    section.name || '',
    row.givenName || '',
    row.surname || '',
    `="${row.personnummer || ''}"`,
    (canvasUser && canvasUser.login_id) || ''
  ]
}

function createCustomColumnsContent ({customColumnsData, customColumns}) {
  const sortedCustomColumns = _.orderBy(customColumns, ['position'], ['asc'])
  return sortedCustomColumns.map(customColumn => customColumnsData[customColumn.id] || '')
}

function createSubmissionLineContent ({student, assignmentIds}) {
  const row = {}
  for (let submission of student.submissions) {
    row['' + submission.assignment_id] = submission.entered_grade || ''
  }
  return assignmentIds.map(id => row[id] || '-')
}

async function createCsvLineContent ({student, ldapClient, assignmentIds, section, canvasUser, customColumns, customColumnsData}) {
  const fixedColumnsContent = await createFixedColumnsContent({student, ldapClient, assignmentIds, section, canvasUser})
  const customColumnsContent = createCustomColumnsContent({customColumnsData, customColumns})
  const assignmentsColumnsContent = createSubmissionLineContent({student, ldapClient, assignmentIds, section, canvasUser})

  return [
    ...fixedColumnsContent,
    ...customColumnsContent,
    ...assignmentsColumnsContent
  ]
}

function exportResults2 (req, res) {
  try {
    // Hack to make Canvas see that the auth is finished and the
    // 'please wait' text can be removed
    res.send(`
  Your download should start automatically. If nothing happens within a few minutes, please go back and try again.

      `)
  } catch (e) {
    log.error('Export failed:', e)
    res.status(500).send('Trasigt')
  }
}

function exportDone (req, res) {
  res.send('Done. The file should now be downloaded to your computer.')
}

async function curriedIsFake ({canvasApi, canvasApiUrl, canvasCourseId}) {
  const fakeUsers = await canvasApi.recursePages(`${canvasApiUrl}/courses/${canvasCourseId}/users?enrollment_type[]=student_view`)
  return function (student) {
    return fakeUsers.find(user => user.id === student.user_id)
  }
}

async function getCustomColumnsFn ({canvasApi, canvasCourseId, canvasApiUrl}) {
  const customColumnsData = {}
  const customColumns = await canvasApi.recursePages(`${canvasApiUrl}/courses/${canvasCourseId}/custom_gradebook_columns`)
  for (let customColumn of customColumns) {
    const data = await canvasApi.recursePages(`${canvasApiUrl}/courses/${canvasCourseId}/custom_gradebook_columns/${customColumn.id}/data`)
    for (let dataEntry of data) {
      customColumnsData[dataEntry.user_id] = customColumnsData[dataEntry.user_id] || {}
      customColumnsData[dataEntry.user_id][customColumn.id] = dataEntry.content
    }
  }
  return {
    customColumns,
    getCustomColumnsData (userId) {
      return customColumnsData[userId] || {}
    }
  }
}

function getCustomColumnHeaders(customColumns){
  return  _.orderBy(customColumns, ['position'], ['asc']).map(c => c.title)
}

async function exportResults3 (req, res) {
  try {
    // log.info('1')
    const fetchedSections = {}
    // log.info('2')
    const courseRound = req.query.courseRound
    // log.info('3')
    const canvasCourseId = req.query.canvasCourseId
    // log.info('4')
    log.info(`Should export for ${courseRound} / ${canvasCourseId}`)
    // Start writing response as soon as possible
    res.set({
      'content-type': 'text/csv; charset=utf-8',
      'location': 'http://www.kth.se'
    })
    // log.info('5')
    res.attachment(`${courseRound || 'canvas'}-results.csv`)
    // log.info('6')
    // Write BOM https://sv.wikipedia.org/wiki/Byte_order_mark
    res.write('\uFEFF')
    // log.info('7')

    const accessToken = await getAccessToken({
      clientId: settings.canvas.clientId,
      clientSecret: settings.canvas.clientSecret,
      redirectUri: req.protocol + '://' + req.get('host') + req.originalUrl,
      code: req.query.code
    })
    // log.info('8')
    const canvasApi = new CanvasApi(canvasApiUrl, accessToken)
    // log.info('9')
    // So far so good, start constructing the output
    const {assignmentIds, headers} = await getAssignmentIdsAndHeaders({canvasApi, canvasCourseId})
    // log.info('10')
    const {getCustomColumnsData, customColumns} = await getCustomColumnsFn({canvasApi, canvasCourseId, canvasApiUrl})
    // log.info('11')
    const fixedColumnHeaders = [
      'SIS User ID',
      'ID',
      'Section',
      'Name',
      'Surname',
      'Personnummer',
      'Email address']
      // log.info('12')
    // Note that the order of these columns has to match that returned from the 'createCsvLineContent' function
    const csvHeader = [
      ...fixedColumnHeaders,
      ...getCustomColumnHeaders(customColumns),
      ...assignmentIds.map(id => headers[id])
    ]
    // log.info('13')
    res.write(csv.createLine(csvHeader))
    // log.info('14')
    const ldapClient = await ldap.getBoundClient()

    const students = await canvasApi.requestUrl(`courses/${canvasCourseId}/students/submissions?grouped=1&student_ids[]=all`)

    // TODO: the following endpoint is deprecated. Change when Instructure has responded on how we should query instead.
    const usersInCourse = await canvasApi.requestUrl(`courses/${canvasCourseId}/students`)

    const isFake = await curriedIsFake({canvasApi, canvasApiUrl, canvasCourseId})

    for (let student of students) {
      if (isFake(student)) {
        continue
      }
      const section = fetchedSections[student.section_id] || await canvasApi.requestCanvas(`sections/${student.section_id}`)
      fetchedSections[student.section_id] = section

      const canvasUser = usersInCourse.find(u => u.id === student.user_id)

      const customColumnsData = getCustomColumnsData(student.user_id)
      const csvLine = await createCsvLineContent({
        student,
        ldapClient,
        assignmentIds,
        section,
        canvasUser,
        customColumns,
        customColumnsData})

      res.write(csv.createLine(csvLine))
    }
    res.send()
    await ldapClient.unbind()
  } catch (e) {
    log.error(`Export failed for query ${req.query}:`, e)
    res.status(500).send(`

                        Åh nej, något gick fel!

                    Försök gärna igen, så håller vi tummarna att det går bättre nästa gång...

Fel:

                  ${e.message}

      `)
  }
}

module.exports = {
  // Do not remove the System controller!
  // System: require('./controllers/systemCtrl'),

  exportResults,
  exportResults2,
  exportResults3,
  exportDone
}
<commit_msg>Added year and time to file name<commit_after>'use strict'
const log = require('./log')
const querystring = require('querystring')
const rp = require('request-promise')
const settings = require('./configuration').server
const CanvasApi = require('kth-canvas-api')
const csv = require('./csvFile')
const ldap = require('./ldap')
const moment = require('moment')
const _ = require('lodash')
const canvasApiUrl = `https://${settings.canvas.host}/api/v1`

function exportResults (req, res) {
  try {
    let b = req.body
    log.info(`The user ${b.lis_person_sourcedid}, ${b.custom_canvas_user_login_id}, is exporting the course ${b.context_label} with id ${b.custom_canvas_course_id}`)
    let courseRound = b.lis_course_offering_sourcedid
    const canvasCourseId = b.custom_canvas_course_id
    const fullUrl = (settings.proxyBase || (req.protocol + '://' + req.get('host'))) + req.originalUrl
    const nextUrl = fullUrl + '2?' + querystring.stringify({courseRound, canvasCourseId})
    log.info('Tell auth to redirect back to', nextUrl)
    log.info('using canvas client id', settings.canvas.clientId)
    const basicUrl = `https://${settings.canvas.host}/login/oauth2/auth?` + querystring.stringify({client_id: settings.canvas.clientId, response_type: 'code', redirect_uri: nextUrl})
    res.redirect(basicUrl)
  } catch (e) {
    log.error('Export failed:', e)
    res.status(500).send('Trasigt')
  }
}

async function getAccessToken ({clientId, clientSecret, redirectUri, code}) {
  const auth = await rp({
    method: 'POST',
    uri: `https://${settings.canvas.host}/login/oauth2/token`,
    body: {
      grant_type: 'authorization_code',
      client_id: clientId,
      client_secret: clientSecret,
      redirect_uri: redirectUri,
      code
    },
    json: true
  })
  return auth.access_token
}

async function getAssignmentIdsAndHeaders ({canvasApi, canvasCourseId}) {
  const assignmentIds = []
  const headers = {}

  const assignments = await canvasApi.recursePages(`${canvasApiUrl}/courses/${canvasCourseId}/assignments`)

  for (let t of assignments) {
    const id = '' + t.id
    assignmentIds.push(id)
    headers[id] = `${t.name} (${t.id})`
  }
  return {assignmentIds, headers}
}

async function createFixedColumnsContent ({student, ldapClient, section, canvasUser}) {
  let row
  try {
    const ugUser = await ldap.lookupUser(ldapClient, student.sis_user_id)
    row = {
      kthid: student.sis_user_id,
      givenName: ugUser.givenName,
      surname: ugUser.sn,
      personnummer: ugUser.norEduPersonNIN
    }
  } catch (err) {
    log.error('An error occured while trying to find user in ldap:', err)
    log.info('No user from ldap, use empty row instead')
    row = {}
  }

  return [
    student.sis_user_id || '',
    student.user_id || '',
    section.name || '',
    row.givenName || '',
    row.surname || '',
    `="${row.personnummer || ''}"`,
    (canvasUser && canvasUser.login_id) || ''
  ]
}

function createCustomColumnsContent ({customColumnsData, customColumns}) {
  const sortedCustomColumns = _.orderBy(customColumns, ['position'], ['asc'])
  return sortedCustomColumns.map(customColumn => customColumnsData[customColumn.id] || '')
}

function createSubmissionLineContent ({student, assignmentIds}) {
  const row = {}
  for (let submission of student.submissions) {
    row['' + submission.assignment_id] = submission.entered_grade || ''
  }
  return assignmentIds.map(id => row[id] || '-')
}

async function createCsvLineContent ({student, ldapClient, assignmentIds, section, canvasUser, customColumns, customColumnsData}) {
  const fixedColumnsContent = await createFixedColumnsContent({student, ldapClient, assignmentIds, section, canvasUser})
  const customColumnsContent = createCustomColumnsContent({customColumnsData, customColumns})
  const assignmentsColumnsContent = createSubmissionLineContent({student, ldapClient, assignmentIds, section, canvasUser})

  return [
    ...fixedColumnsContent,
    ...customColumnsContent,
    ...assignmentsColumnsContent
  ]
}

function exportResults2 (req, res) {
  try {
    // Hack to make Canvas see that the auth is finished and the
    // 'please wait' text can be removed
    res.send(`
  Your download should start automatically. If nothing happens within a few minutes, please go back and try again.

      `)
  } catch (e) {
    log.error('Export failed:', e)
    res.status(500).send('Trasigt')
  }
}

function exportDone (req, res) {
  res.send('Done. The file should now be downloaded to your computer.')
}

async function curriedIsFake ({canvasApi, canvasApiUrl, canvasCourseId}) {
  const fakeUsers = await canvasApi.recursePages(`${canvasApiUrl}/courses/${canvasCourseId}/users?enrollment_type[]=student_view`)
  return function (student) {
    return fakeUsers.find(user => user.id === student.user_id)
  }
}

async function getCustomColumnsFn ({canvasApi, canvasCourseId, canvasApiUrl}) {
  const customColumnsData = {}
  const customColumns = await canvasApi.recursePages(`${canvasApiUrl}/courses/${canvasCourseId}/custom_gradebook_columns`)
  for (let customColumn of customColumns) {
    const data = await canvasApi.recursePages(`${canvasApiUrl}/courses/${canvasCourseId}/custom_gradebook_columns/${customColumn.id}/data`)
    for (let dataEntry of data) {
      customColumnsData[dataEntry.user_id] = customColumnsData[dataEntry.user_id] || {}
      customColumnsData[dataEntry.user_id][customColumn.id] = dataEntry.content
    }
  }
  return {
    customColumns,
    getCustomColumnsData (userId) {
      return customColumnsData[userId] || {}
    }
  }
}

function getCustomColumnHeaders(customColumns){
  return  _.orderBy(customColumns, ['position'], ['asc']).map(c => c.title)
}

async function exportResults3 (req, res) {
  try {
    // log.info('1')
    const fetchedSections = {}
    // log.info('2')
    const courseRound = req.query.courseRound
    // log.info('3')
    const canvasCourseId = req.query.canvasCourseId
    // log.info('4')
    log.info(`Should export for ${courseRound} / ${canvasCourseId}`)
    // Start writing response as soon as possible
    res.set({
      'content-type': 'text/csv; charset=utf-8',
      'location': 'http://www.kth.se'
    })
    // log.info('5')
    res.attachment(`${courseRound || 'canvas'}-${moment().format("YYYYMMDD-HHMMSS")}-results.csv`)
    // log.info('6')
    // Write BOM https://sv.wikipedia.org/wiki/Byte_order_mark
    res.write('\uFEFF')
    // log.info('7')

    const accessToken = await getAccessToken({
      clientId: settings.canvas.clientId,
      clientSecret: settings.canvas.clientSecret,
      redirectUri: req.protocol + '://' + req.get('host') + req.originalUrl,
      code: req.query.code
    })
    // log.info('8')
    const canvasApi = new CanvasApi(canvasApiUrl, accessToken)
    // log.info('9')
    // So far so good, start constructing the output
    const {assignmentIds, headers} = await getAssignmentIdsAndHeaders({canvasApi, canvasCourseId})
    // log.info('10')
    const {getCustomColumnsData, customColumns} = await getCustomColumnsFn({canvasApi, canvasCourseId, canvasApiUrl})
    // log.info('11')
    const fixedColumnHeaders = [
      'SIS User ID',
      'ID',
      'Section',
      'Name',
      'Surname',
      'Personnummer',
      'Email address']
      // log.info('12')
    // Note that the order of these columns has to match that returned from the 'createCsvLineContent' function
    const csvHeader = [
      ...fixedColumnHeaders,
      ...getCustomColumnHeaders(customColumns),
      ...assignmentIds.map(id => headers[id])
    ]
    // log.info('13')
    res.write(csv.createLine(csvHeader))
    // log.info('14')
    const ldapClient = await ldap.getBoundClient()

    const students = await canvasApi.requestUrl(`courses/${canvasCourseId}/students/submissions?grouped=1&student_ids[]=all`)

    // TODO: the following endpoint is deprecated. Change when Instructure has responded on how we should query instead.
    const usersInCourse = await canvasApi.requestUrl(`courses/${canvasCourseId}/students`)

    const isFake = await curriedIsFake({canvasApi, canvasApiUrl, canvasCourseId})

    for (let student of students) {
      if (isFake(student)) {
        continue
      }
      const section = fetchedSections[student.section_id] || await canvasApi.requestCanvas(`sections/${student.section_id}`)
      fetchedSections[student.section_id] = section

      const canvasUser = usersInCourse.find(u => u.id === student.user_id)

      const customColumnsData = getCustomColumnsData(student.user_id)
      const csvLine = await createCsvLineContent({
        student,
        ldapClient,
        assignmentIds,
        section,
        canvasUser,
        customColumns,
        customColumnsData})

      res.write(csv.createLine(csvLine))
    }
    res.send()
    await ldapClient.unbind()
  } catch (e) {
    log.error(`Export failed for query ${req.query}:`, e)
    res.status(500).send(`

                        Åh nej, något gick fel!

                    Försök gärna igen, så håller vi tummarna att det går bättre nästa gång...

Fel:

                  ${e.message}

      `)
  }
}

module.exports = {
  // Do not remove the System controller!
  // System: require('./controllers/systemCtrl'),

  exportResults,
  exportResults2,
  exportResults3,
  exportDone
}
<|endoftext|>


<commit_before>// @flow
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')
const charsLength = chars.length

/* Some high number, usually 9-digit base-10. Map it to base-😎 */
const generateAlphabeticName = (code: number): string => {
  let name = ''
  let x

  for (x = code; x > charsLength; x = Math.floor(x / charsLength)) {
    name = chars[x % charsLength] + name
  }

  return chars[x % charsLength] + name
}

export default generateAlphabeticName
<commit_msg>Refactor generateAlphabeticName for shrinking bundlesize<commit_after>// @flow
/* eslint-disable no-bitwise */

/* This is the "capacity" of our alphabet i.e. 2x26 for all letters plus their capitalised
 * counterparts */
const charsLength = 52

/* start at 75 for 'a' until 'z' (25) and then start at 65 for capitalised letters */
const getAlphabeticChar = (code: number): string =>
  String.fromCharCode(code + (code > 25 ? 39 : 97))

/* input a number, usually a hash and convert it to base-52 */
const generateAlphabeticName = (code: number): string => {
  let name = ''
  let x

  /* get a char and divide by alphabet-length (bitwise zero for flooring the number) */
  for (x = code | 0; x > charsLength; x = (x / charsLength) | 0) {
    name = getAlphabeticChar(x % charsLength) + name
  }

  return getAlphabeticChar(x % charsLength) + name
}

export default generateAlphabeticName
<|endoftext|>


<commit_before>window.numeral = this.numeral; //needed by numeral.de-de.js

function parseDatacolumn(DATACOLUMN) {
  var obj = {};

  for (var i = 0, ilen = DATACOLUMN.attributes.length; i < ilen; i++) {
    obj[DATACOLUMN.attributes[i].name] = DATACOLUMN.attributes[i].value || true;
  }

  obj.data = obj.value;
  delete obj.value;

  obj.readOnly = obj.readonly;
  delete obj.readonly;

  obj.checkedTemplate = obj.checkedtemplate;
  delete obj.checkedtemplate;

  obj.uncheckedTemplate = obj.uncheckedtemplate;
  delete obj.uncheckedtemplate;

  if (obj.type === 'autocomplete' && typeof obj.source === 'string') {
    obj.source = window[obj.source];
  }

  return obj;
}

var publicMethods = ['updateSettings', 'loadData', 'render', 'setDataAtCell', 'setDataAtRowProp', 'getDataAtCell', 'getDataAtRowProp', 'countRows', 'countCols', 'rowOffset', 'colOffset', 'countVisibleRows', 'countVisibleCols', 'clear', 'clearUndo', 'getData', 'alter', 'getCell', 'getCellMeta', 'selectCell', 'deselectCell', 'getSelected', 'destroyEditor', 'getRowHeader', 'getColHeader', 'destroy', 'isUndoAvailable', 'isRedoAvailable', 'undo', 'redo', 'countEmptyRows', 'countEmptyCols', 'isEmptyRow', 'isEmptyCol'];

var publish = {};
for (var i = 0, ilen = publicMethods.length; i < ilen; i++) {
  publish[publicMethods[i]] = (function (methodName) {
    return function () {
      return this.instance[methodName].apply(this.instance, arguments);
    }
  })(publicMethods[i]);
}

Toolkit.register(this, {
  instance: null,
  ready: function () {
    var DATACOLUMNs = this.querySelectorAll('datacolumn');
    var columns = [];
    for (var i = 0, ilen = DATACOLUMNs.length; i < ilen; i++) {
      columns.push(parseDatacolumn(DATACOLUMNs[i]));
    }

    var options = {
      data: window[this.datarows],
      columns: columns,
      minRows: 5,
      minCols: 6,
      minSpareRows: 1,
      autoWrapRow: true,
      colHeaders: true,
      contextMenu: true
    };

    jQuery(this.$.htContainer).handsontable(options);

    this.instance = jQuery(this.$.htContainer).data('handsontable');
  },
  publish: publish
});<commit_msg>add parseSettingsFromDOM<commit_after>window.numeral = this.numeral; //needed by numeral.de-de.js

function parseDatacolumn(DATACOLUMN) {
  var obj = {};

  for (var i = 0, ilen = DATACOLUMN.attributes.length; i < ilen; i++) {
    obj[DATACOLUMN.attributes[i].name] = DATACOLUMN.attributes[i].value || true;
  }

  obj.data = obj.value;
  delete obj.value;

  obj.readOnly = obj.readonly;
  delete obj.readonly;

  obj.checkedTemplate = obj.checkedtemplate;
  delete obj.checkedtemplate;

  obj.uncheckedTemplate = obj.uncheckedtemplate;
  delete obj.uncheckedtemplate;

  if (obj.type === 'autocomplete' && typeof obj.source === 'string') {
    obj.source = window[obj.source];
  }

  return obj;
}

var publicMethods = ['updateSettings', 'loadData', 'render', 'setDataAtCell', 'setDataAtRowProp', 'getDataAtCell', 'getDataAtRowProp', 'countRows', 'countCols', 'rowOffset', 'colOffset', 'countVisibleRows', 'countVisibleCols', 'clear', 'clearUndo', 'getData', 'alter', 'getCell', 'getCellMeta', 'selectCell', 'deselectCell', 'getSelected', 'destroyEditor', 'getRowHeader', 'getColHeader', 'destroy', 'isUndoAvailable', 'isRedoAvailable', 'undo', 'redo', 'countEmptyRows', 'countEmptyCols', 'isEmptyRow', 'isEmptyCol', 'parseSettingsFromDOM'];

var publish = {};
for (var i = 0, ilen = publicMethods.length; i < ilen; i++) {
  publish[publicMethods[i]] = (function (methodName) {
    return function () {
      return this.instance[methodName].apply(this.instance, arguments);
    }
  })(publicMethods[i]);
}

Toolkit.register(this, {
  instance: null,
  ready: function () {
    var DATACOLUMNs = this.querySelectorAll('datacolumn');
    var columns = [];
    for (var i = 0, ilen = DATACOLUMNs.length; i < ilen; i++) {
      columns.push(parseDatacolumn(DATACOLUMNs[i]));
    }

    var options = {
      data: window[this.datarows],
      columns: columns,
      minRows: 5,
      minCols: 6,
      minSpareRows: 1,
      autoWrapRow: true,
      colHeaders: true,
      contextMenu: true
    };

    jQuery(this.$.htContainer).handsontable(options);

    this.instance = jQuery(this.$.htContainer).data('handsontable');
  },
  publish: publish
});<|endoftext|>


<commit_before>var musicCenterOpen = false;

$(function() {
	$("#misskey-main-header > .main .mainContentsContainer .left nav .mainNav .misskey").click(function() {
		if (musicCenterOpen) {
			$("#misskey-musicCenter").css('top', '-100%');
		} else {
			$("#misskey-musicCenter").css('top', '0');
		}
		musicCenterOpen = !musicCenterOpen;
	});
	$("body").css("margin-top", $("body > #misskey-main-header").outerHeight() + "px");

	$("#misskey-main-header .search input").keyup(function() {
		var $result = $("#misskey-main-header .search .result");
		if ($(this).val() == '') {
			$result.empty();
			return;
		}
		$.ajax('https://api.misskey.xyz/search/user', {
			type: 'get',
			data: { 'query': $(this).val() },
			dataType: 'json',
			xhrFields: { withCredentials: true }
		}).done(function(result) {
			$result.empty();
			if (result.length > 0) {
				$result.append($('
'));
				result.forEach(function(user) {
					$result.find('ol').append(
						$('
').append(
							$('').attr({
								'href': 'https://misskey.xyz/' + user.screenName,
								'title': user.comment,
							}).append(
								$('').attr('src', 'https://misskey.xyz/img/icon/' + user.screenName)
							).append(
								$('').text(user.name)
							).append(
								$('').text('@' + user.screenName)
							)
						)
					);
				});
			}
		}).fail(function() {
		});
	});
});

$(window).load(function() {
	$("body").css("margin-top", $("body > #misskey-main-header").outerHeight() + "px");
});<commit_msg>Display unread count<commit_after>var musicCenterOpen = false;

$(function() {
	$.ajax('https://api.misskey.xyz/account/unreadalltalks_count', {
		type: 'get',
		dataType: 'json',
		xhrFields: {withCredentials: true}
	}).done(function(result) {
		$("#misskey-main-header > .main .mainContentsContainer .left nav .mainNav ul .talk").append(
			$('').text(result));
	}).fail(function() {
	});

	$("#misskey-main-header > .main .mainContentsContainer .left nav .mainNav .misskey").click(function() {
		if (musicCenterOpen) {
			$("#misskey-musicCenter").css('top', '-100%');
		} else {
			$("#misskey-musicCenter").css('top', '0');
		}
		musicCenterOpen = !musicCenterOpen;
	});
	$("body").css("margin-top", $("body > #misskey-main-header").outerHeight() + "px");

	$("#misskey-main-header .search input").keyup(function() {
		var $result = $("#misskey-main-header .search .result");
		if ($(this).val() == '') {
			$result.empty();
			return;
		}
		$.ajax('https://api.misskey.xyz/search/user', {
			type: 'get',
			data: { 'query': $(this).val() },
			dataType: 'json',
			xhrFields: { withCredentials: true }
		}).done(function(result) {
			$result.empty();
			if (result.length > 0) {
				$result.append($('
'));
				result.forEach(function(user) {
					$result.find('ol').append(
						$('
').append(
							$('').attr({
								'href': 'https://misskey.xyz/' + user.screenName,
								'title': user.comment,
							}).append(
								$('').attr('src', 'https://misskey.xyz/img/icon/' + user.screenName)
							).append(
								$('').text(user.name)
							).append(
								$('').text('@' + user.screenName)
							)
						)
					);
				});
			}
		}).fail(function() {
		});
	});
});

$(window).load(function() {
	$("body").css("margin-top", $("body > #misskey-main-header").outerHeight() + "px");
});<|endoftext|>


<commit_before>import test from 'ava';

import { Flow } from '../src/flow';
import { FlowRegistryMixin } from '../src/flow-registry-mixin';
import { Step } from 'kronos-step';

const owner = new (FlowRegistryMixin(
  class Base {
    emit(name, arg1, arg2) {} // dummy event emitter
  }
))();

class MyStep extends Step {
  static get name() {
    return 'slow-start';
  }

  constructor(config, owner) {
    super(config, owner);
    this.time = config.time || 0;
  }

  toJSONWithOptions(options = {}) {
    const json = super.toJSONWithOptions(options);

    json.time = this.time;

    return json;
  }

  _start() {
    return new Promise((fulfill, reject) =>
      setTimeout(() => fulfill(this), this.time)
    );
  }

  _stop() {
    return new Promise((fulfill, reject) =>
      setTimeout(() => fulfill(this), this.time)
    );
  }
}

owner.registerStep(MyStep);

function makeFlow(owner) {
  return new Flow(
    {
      name: 'myFlow1',
      description: 'my out-step description',

      steps: {
        step1: {
          type: 'slow-start',
          time: 10
        }
      }
    },
    owner
  );
}

test('flow constructor', t => {
  const flow = makeFlow(owner);
  t.is(flow.name, 'myFlow1');
  t.is(flow.steps.get('step1').name, 'step1');
  t.is(flow.steps.get('step1').time, 10);
});

test('flow json', t => {
  const flow = makeFlow(owner);
  const json = flow.toJSONWithOptions();
  t.deepEqual(json, {
    //name: 'myFlow1',
    type: 'kronos-flow',
    //description: 'my out-step description',
    endpoints: {},

    steps: {
      step1: {
        type: 'slow-start',
        endpoints: {},
        time: 10
      }
    }
  });
});

test('flow autostart false', async t => {
  const f = new Flow(
    {
      name: 'myFlow',
      type: 'kronos-flow',
      steps: {
        slowInbound: {
          type: 'slow-start',
          time: 10
        }
      }
    },
    owner
  );

  t.is(f.name, 'myFlow');
  t.is(f.autostart, false);
});

test('flow autostart true', async t => {
  const f = new Flow(
    {
      name: 'myFlow',
      type: 'kronos-flow',
      autostart: true,
      steps: {
        slowInbound: {
          type: 'slow-start',
          time: 10
        }
      }
    },
    owner
  );

  t.is(f.name, 'myFlow');
  t.is(f.autostart, true);
});

/*

  describe('connections', () => {
    describe('service', () => {
      describe('optional', () => {
        it('create', done => {
          const s = manager.createStepInstanceFromConfig(
            {
              name: 'myFlowName',
              type: 'kronos-flow',
              steps: {
                'with-service': {
                  type: 'slow-start',
                  endpoints: {
                    optional: {
                      in: true,
                      target: 'aService:a1',
                      mandatory: false
                    }
                  }
                }
              }
            },
            manager
          );
          s.start().then(() => s.stop().then(() => done()));
        });
      });
      describe('mandatory', () => {
        describe('present', () => {
          it('create', done => {
            const s = manager.createStepInstanceFromConfig(
              {
                name: 'myFlowName',
                type: 'kronos-flow',
                steps: {
                  'with-service': {
                    type: 'slow-start',
                    endpoints: {
                      mandatory: {
                        out: true,
                        target: 'config:config'
                      }
                    }
                  }
                }
              },
              manager
            );
            s.start().then(() => s.stop().then(() => done()));
          });
        });

        describe('missing service', () => {
          it('create', done => {
            class TestService extends service.Service {
              static get name() {
                return 'testService';
              }
              get type() {
                return TestService.name;
              }
              constructor(config, owner) {
                super(config, owner);
                this.addEndpoint(
                  new endpoint.ReceiveEndpoint('a1', this)
                ).receive = entry => Promise.resolve();
              }
            }

            const s = manager.createStepInstanceFromConfig(
              {
                name: 'myFlowName',
                type: 'kronos-flow',
                steps: {
                  'with-service': {
                    type: 'slow-start',
                    endpoints: {
                      mandatory: {
                        out: true,
                        target: 'testService:a1',
                        mandatory: true
                      }
                    }
                  }
                }
              },
              manager
            );

            manager.registerServiceFactory(TestService);

            s.start().then(() => s.stop().then(() => done()));
          });
        });
        describe('missing service endpoint', () => {
          it('create', () => {
            try {
              manager.createStepInstanceFromConfig(
                {
                  name: 'myFlowName',
                  type: 'kronos-flow',
                  steps: {
                    'with-service': {
                      type: 'slow-start',
                      endpoints: {
                        mandatory: {
                          in: true,
                          target: 'config:a1'
                        }
                      }
                    }
                  }
                },
                manager
              );
            } catch (e) {
              assert.match(e, /service 'config' not found/);
            }
          });
        });
      });
    });

    describe('step', () => {
      describe('mandatory', () => {
        describe('missing step', () => {
          it('create', () => {
            try {
              manager.createStepInstanceFromConfig(
                {
                  name: 'myFlowName',
                  type: 'kronos-flow',
                  steps: {
                    s1: {
                      type: 'slow-start',
                      endpoints: {
                        mandatory: {
                          in: true,
                          target: 'aStep/a1',
                          mandatory: true
                        }
                      }
                    }
                  }
                },
                manager
              );
            } catch (e) {
              assert.match(e, /Step 'aStep' not found/);
            }
          });
        });
        describe('missing step endpoint', () => {
          it('create', () => {
            try {
              manager.createStepInstanceFromConfig(
                {
                  name: 'myFlowName',
                  type: 'kronos-flow',
                  steps: {
                    s1: {
                      type: 'slow-start',
                      endpoints: {
                        mandatory: {
                          in: true,
                          target: 's1/a1'
                        }
                      }
                    }
                  }
                },
                manager
              );
            } catch (e) {
              assert.match(e, /step 's1' not found/);
            }
          });
        });
      });
    });

    before(() =>
      Flow.loadFlows(manager, {
        myFlowName: {
          type: 'kronos-flow',
          steps: {
            normal: {
              type: 'slow-start',
              time: 5
            }
          }
        }
      })
    );

    it('basic', done => {
      const s = manager.flows.myFlowName;
      s.start().then(() =>
        s.stop().then(() => {
          done();
        })
      );
    });
  });
});
*/
<commit_msg>test: wup<commit_after>import test from 'ava';

import { Flow } from '../src/flow';
import { FlowRegistryMixin } from '../src/flow-registry-mixin';
import { Step } from 'kronos-step';

const owner = new (FlowRegistryMixin(
  class Base {
    emit(name, arg1, arg2) {} // dummy event emitter
  }
))();

class MyStep extends Step {
  static get name() {
    return 'slow-start';
  }

  constructor(config, owner) {
    super(config, owner);
    this.time = config.time || 0;
  }

  toJSONWithOptions(options = {}) {
    const json = super.toJSONWithOptions(options);

    json.time = this.time;

    return json;
  }

  _start() {
    return new Promise((fulfill, reject) =>
      setTimeout(() => fulfill(this), this.time)
    );
  }

  _stop() {
    return new Promise((fulfill, reject) =>
      setTimeout(() => fulfill(this), this.time)
    );
  }
}

owner.registerStep(MyStep);

function makeFlow(owner) {
  return new Flow(
    {
      name: 'myFlow1',
      description: 'my out-step description',

      steps: {
        step1: {
          type: 'slow-start',
          time: 10
        }
      }
    },
    owner
  );
}

test('flow constructor', t => {
  const flow = makeFlow(owner);
  t.is(flow.name, 'myFlow1');
  t.is(flow.steps.get('step1').name, 'step1');
  t.is(flow.steps.get('step1').type, 'slow-start');
  t.is(flow.steps.get('step1').time, 10);
});

test('flow json', t => {
  const flow = makeFlow(owner);
  const json = flow.toJSONWithOptions();
  t.deepEqual(json, {
    //name: 'myFlow1',
    type: 'kronos-flow',
    //description: 'my out-step description',
    endpoints: {},

    steps: {
      step1: {
        type: 'slow-start',
        endpoints: {},
        time: 10
      }
    }
  });
});

test('flow autostart false', async t => {
  const f = new Flow(
    {
      name: 'myFlow',
      type: 'kronos-flow',
      steps: {
        slowInbound: {
          type: 'slow-start',
          time: 10
        }
      }
    },
    owner
  );

  t.is(f.name, 'myFlow');
  t.is(f.autostart, false);
});

test('flow autostart true', async t => {
  const f = new Flow(
    {
      name: 'myFlow',
      type: 'kronos-flow',
      autostart: true,
      steps: {
        slowInbound: {
          type: 'slow-start',
          time: 10
        }
      }
    },
    owner
  );

  t.is(f.name, 'myFlow');
  t.is(f.autostart, true);
});

/*

  describe('connections', () => {
    describe('service', () => {
      describe('optional', () => {
        it('create', done => {
          const s = manager.createStepInstanceFromConfig(
            {
              name: 'myFlowName',
              type: 'kronos-flow',
              steps: {
                'with-service': {
                  type: 'slow-start',
                  endpoints: {
                    optional: {
                      in: true,
                      target: 'aService:a1',
                      mandatory: false
                    }
                  }
                }
              }
            },
            manager
          );
          s.start().then(() => s.stop().then(() => done()));
        });
      });
      describe('mandatory', () => {
        describe('present', () => {
          it('create', done => {
            const s = manager.createStepInstanceFromConfig(
              {
                name: 'myFlowName',
                type: 'kronos-flow',
                steps: {
                  'with-service': {
                    type: 'slow-start',
                    endpoints: {
                      mandatory: {
                        out: true,
                        target: 'config:config'
                      }
                    }
                  }
                }
              },
              manager
            );
            s.start().then(() => s.stop().then(() => done()));
          });
        });

        describe('missing service', () => {
          it('create', done => {
            class TestService extends service.Service {
              static get name() {
                return 'testService';
              }
              get type() {
                return TestService.name;
              }
              constructor(config, owner) {
                super(config, owner);
                this.addEndpoint(
                  new endpoint.ReceiveEndpoint('a1', this)
                ).receive = entry => Promise.resolve();
              }
            }

            const s = manager.createStepInstanceFromConfig(
              {
                name: 'myFlowName',
                type: 'kronos-flow',
                steps: {
                  'with-service': {
                    type: 'slow-start',
                    endpoints: {
                      mandatory: {
                        out: true,
                        target: 'testService:a1',
                        mandatory: true
                      }
                    }
                  }
                }
              },
              manager
            );

            manager.registerServiceFactory(TestService);

            s.start().then(() => s.stop().then(() => done()));
          });
        });
        describe('missing service endpoint', () => {
          it('create', () => {
            try {
              manager.createStepInstanceFromConfig(
                {
                  name: 'myFlowName',
                  type: 'kronos-flow',
                  steps: {
                    'with-service': {
                      type: 'slow-start',
                      endpoints: {
                        mandatory: {
                          in: true,
                          target: 'config:a1'
                        }
                      }
                    }
                  }
                },
                manager
              );
            } catch (e) {
              assert.match(e, /service 'config' not found/);
            }
          });
        });
      });
    });

    describe('step', () => {
      describe('mandatory', () => {
        describe('missing step', () => {
          it('create', () => {
            try {
              manager.createStepInstanceFromConfig(
                {
                  name: 'myFlowName',
                  type: 'kronos-flow',
                  steps: {
                    s1: {
                      type: 'slow-start',
                      endpoints: {
                        mandatory: {
                          in: true,
                          target: 'aStep/a1',
                          mandatory: true
                        }
                      }
                    }
                  }
                },
                manager
              );
            } catch (e) {
              assert.match(e, /Step 'aStep' not found/);
            }
          });
        });
        describe('missing step endpoint', () => {
          it('create', () => {
            try {
              manager.createStepInstanceFromConfig(
                {
                  name: 'myFlowName',
                  type: 'kronos-flow',
                  steps: {
                    s1: {
                      type: 'slow-start',
                      endpoints: {
                        mandatory: {
                          in: true,
                          target: 's1/a1'
                        }
                      }
                    }
                  }
                },
                manager
              );
            } catch (e) {
              assert.match(e, /step 's1' not found/);
            }
          });
        });
      });
    });

    before(() =>
      Flow.loadFlows(manager, {
        myFlowName: {
          type: 'kronos-flow',
          steps: {
            normal: {
              type: 'slow-start',
              time: 5
            }
          }
        }
      })
    );

    it('basic', done => {
      const s = manager.flows.myFlowName;
      s.start().then(() =>
        s.stop().then(() => {
          done();
        })
      );
    });
  });
});
*/
<|endoftext|>


<commit_before>/*jslint node: true, vars: true */
/*global describe: false, it: false */

"use strict";

var assert = require("assert");

var gcp = require("../lib/gce");

describe("gcp", function () {

    it("returns greatest common path", function () {
        assert.deepEqual(gcp([ ["a", "b"], ["a"]]), "a");
        assert.deepEqual(gcp([ ["a", "b"], ["a", "b", "c"]]), "b");
    });

    it("returns null if no common path", function () {
        assert.deepEqual(gcp([ ["a", "b"], ["c"]]), null);
        assert.deepEqual(gcp([ [], ["a"]]), null);
        assert.deepEqual(gcp([ [], []]), null);
    });

});
<commit_msg>Test name cleanup.<commit_after>/*jslint node: true, vars: true */
/*global describe: false, it: false */

"use strict";

var assert = require("assert");

var gcp = require("../lib/gce");

describe("gce", function () {

    it("returns greatest common element", function () {
        assert.deepEqual(gcp([ ["a", "b"], ["a"]]), "a");
        assert.deepEqual(gcp([ ["a", "b"], ["a", "b", "c"]]), "b");
    });

    it("returns null if no common element", function () {
        assert.deepEqual(gcp([ ["a", "b"], ["c"]]), null);
        assert.deepEqual(gcp([ [], ["a"]]), null);
        assert.deepEqual(gcp([ [], []]), null);
    });

});
<|endoftext|>