define([
    'testUtil',
    'common/runtime',
    'base/js/namespace',
    'kbaseNarrative',
    'widgets/appWidgets2/input/toggleButtonInput'
], (
    TestUtil,
    Runtime,
    Jupyter,
    Narrative,
    ToggleButtonInput
) => {
    'use strict';
    let bus,
        testConfig,
        required = false,
        runtime = Runtime.make(),
        node,
        defaultValue = true;

    function buildTestConfig(required, defaultValue, bus) {
        return {
            bus: bus,
            parameterSpec: {
                data: {
                    defaultValue: defaultValue,
                    nullValue: null,
                    constraints: {
                        required: required
                    }
                },
                defaultValue: () => defaultValue,
                required: () => required
            },
            channelName: bus.channelName
        };
    }

    describe('ToggleButtonInput tests', () => {
        beforeEach(() => {
            node = document.createElement('div');
            bus = runtime.bus().makeChannelBus({
                description: 'toggle button testing',
            });
            testConfig = buildTestConfig(required, defaultValue, bus);

            if (TestUtil.getAuthToken()) {
                document.cookie = 'kbase_session=' + TestUtil.getAuthToken();
                Jupyter.narrative = new Narrative();
                Jupyter.narrative.authToken = TestUtil.getAuthToken();
                Jupyter.narrative.userId = TestUtil.getUserId();
            }
        });

        it('Should load the widget', () => {
            expect(ToggleButtonInput).not.toBeNull();
        });

        it('Should instantiate a widget', (done) => {
            let widget = ToggleButtonInput.make(testConfig);
            expect(widget).toBeDefined();
            expect(widget.start).toBeDefined();

            // fires 'sync' after starting, then we can tell it to 'update',
            // which does the rendering. THEN we can examine that it's rendered right.
            bus.on('sync', () => {
                expect(node.querySelector('[data-element="main-panel"]')).toBeDefined();
                bus.emit('update', {value: true});
                setTimeout(() => {
                    let inputElem = node.querySelector('input[type="checkbox"]');
                    expect(inputElem).toBeDefined();
                    expect(inputElem.getAttribute('checked')).not.toBeNull();
                    done();
                }, 100);
            });

            widget.start()
                .then(() => {
                    bus.emit('run', {node: node});
                });
        });

        it('Should update value and reset properly via bus', (done, fail) => {
            // start with one value, change it, then reset.
            // check along the way.
            let widget = ToggleButtonInput.make(testConfig);
            bus.on('sync', () => {
                bus.emit('update', {value: defaultValue}); // no change, just verify it's there.
                TestUtil.wait(100)
                    .then(() => {
                        let inputElem = node.querySelector('input[type="checkbox"]');
                        expect(inputElem.getAttribute('checked')).not.toBeNull();
                        bus.emit('update', {value: 0});
                        return TestUtil.wait(100);
                    })
                    .then(() => {
                        let inputElem = node.querySelector('input[type="checkbox"]');
                        expect(inputElem.getAttribute('checked')).toBeNull();
                        bus.emit('reset-to-defaults');
                        return TestUtil.wait(100);
                    })
                    .then(() => {
                        let inputElem = node.querySelector('input[type="checkbox"]');
                        expect(inputElem.getAttribute('checked')).not.toBeNull();
                        done();
                    })
                    .catch(fail);
            });
            widget.start().then(() => {bus.emit('run', {node: node})});
        });

        it('Should respond to input change events with "changed"', (done) => {
            let widget = ToggleButtonInput.make(testConfig);
            bus.on('sync', () => {
                bus.emit('update', {value: defaultValue});
                TestUtil.wait(100)
                    .then(() => {
                        let inputElem = node.querySelector('input[type="checkbox"]');
                        expect(inputElem.getAttribute('checked')).not.toBeNull();
                        inputElem.dispatchEvent(new Event('change'));
                    });
            });
            bus.on('changed', (message) => {
                expect(message.newValue).toBeTruthy();
                done();
            });

            widget.start().then(() => {bus.emit('run', {node: node})});
        });

        it('Should respond to input change events with "validation"', (done) => {
            let widget = ToggleButtonInput.make(testConfig);
            bus.on('sync', () => {
                bus.emit('update', {value: defaultValue});
                TestUtil.wait(100)
                    .then(() => {
                        let inputElem = node.querySelector('input[type="checkbox"]');
                        expect(inputElem.getAttribute('checked')).not.toBeNull();
                        inputElem.dispatchEvent(new Event('change'));
                    });
            });
            bus.on('validation', (message) => {
                expect(message.errorMessage).toBeUndefined();
                expect(message.diagnosis).toBe('valid');
                done();
            });

            widget.start().then(() => {bus.emit('run', {node: node})});
        });
    });
})

@@ -1220,333 +1220,8 @@
 us);
-%0A%0A            if (TestUtil.getAuthToken()) %7B%0A                document.cookie = 'kbase_session=' + TestUtil.getAuthToken();%0A                Jupyter.narrative = new Narrative();%0A                Jupyter.narrative.authToken = TestUtil.getAuthToken();%0A                Jupyter.narrative.userId = TestUtil.getUserId();%0A            %7D
 %0A   
@@ -3864,32 +3864,38 @@
 changed%22', (done
+, fail
 ) =%3E %7B%0A         
@@ -4062,33 +4062,33 @@
   TestUtil.wait(
-1
+2
 00)%0A            
@@ -4361,32 +4361,65 @@
               %7D)
+%0A                    .catch(fail)
 ;%0A            %7D)

update togglebutton input