Example #1
0
  let checkObjects = async function(context, assert, subjectNum, subjectVal, expectedObjects){
    assert.expect(expectedObjects.length + 2);
    const school = context.server.create('school', { title: 'first' });
    const mockUser = EmberObject.create({
      school: resolve(school)
    });

    const currentUserMock = Service.extend({
      model: resolve(mockUser)
    });
    context.owner.register('service:current-user', currentUserMock);
    context.set('close', ()=>{});
    await render(hbs`{{new-myreport close=(action close)}}`);

    const subject = `[data-test-subject] select`;
    const object = `[data-test-object] select`;
    await fillIn('[data-test-school] select', 'null');
    const subjectSelect = find(subject);
    assert.equal(subjectSelect.options[subjectNum].value, subjectVal);
    await fillIn(subjectSelect, subjectVal);

    const objectSelect = find(object);
    assert.equal(objectSelect.options[0].value, '');
    expectedObjects.forEach((val, i) => {
      assert.equal(objectSelect.options[i + 1].value, val, `${val} is object option`);
    });
  };
Example #2
0
  test('remove learnergroup', async function (assert) {
    this.user.update({administeredSchools: [this.school]});
    assert.expect(3);

    this.server.create('program', {
      schoolId: 1,
    });
    this.server.create('programYear', {
      programId: 1,
    });
    this.server.create('cohort', {
      programYearId: 1,
    });
    this.server.create('learnerGroup', {
      cohortId: 1,
      id: 1,
    });
    this.server.create('learnerGroup', {
      cohortId: 1,
      parentId: 1,
    });
    await visit('/learnergroups');
    assert.equal(1, findAll('.list tbody tr').length);
    assert.equal(await getElementText(find(find('.list tbody tr:nth-of-type(1) td'))), getText('learnergroup 0'));
    await click('.list tbody tr:nth-of-type(1) td:nth-of-type(4) .remove');
    await click('.list tbody tr:nth-of-type(2) .remove');
    assert.equal(0, findAll('.list tbody tr').length);
  });
  test('Compliance Purge Policy', async function(assert) {
    assert.expect(3);

    const downstreamClass = '.downstream-purge-policy';
    const defaultMissingText = 'This dataset does not have a current compliance purge policy';
    const { server } = this;
    const { platform, uri } = server.create('datasetView');

    this.set('urn', uri);
    this.set('platform', platform);
    await render(hbs`{{datasets/containers/upstream-dataset urn=urn platform=platform}}`);

    await waitUntil(() => find(downstreamClass));

    assert.equal(
      find(downstreamClass).textContent.trim(),
      defaultMissingText,
      'Shows the missing text string when there is no purge policy set'
    );

    assert.ok(find(downstreamPolicyEditButton), 'policy is editable');

    server.create('platform');
    server.create('retention');

    await render(hbs`{{datasets/containers/upstream-dataset urn=urn platform=platform}}`);

    await waitUntil(() => find(purgePolicyClass) && find(purgePolicyClass).textContent.trim() !== defaultMissingText);

    assert.ok(find.bind(find, purgePolicyClass), 'purge policy radio is rendered');
  });
  test('row selection - click to modify selection', async function(assert) {
    this.set('table', new Table(Columns, this.server.createList('user', 5)));

    await render(
      hbs `{{lt-body table=table sharedOptions=sharedOptions canSelect=true multiSelect=true multiSelectRequiresKeyboard=false}}`
    );

    let firstRow = find('tr:first-child');
    let middleRow = find('tr:nth-child(4)');
    let lastRow = find('tr:last-child');

    assert.equal(findAll('tbody > tr').length, 5);

    await click(firstRow);
    assert.equal(findAll('tr.is-selected').length, 1, 'clicking a row selects it');

    await click(lastRow, { shiftKey: true });
    assert.equal(findAll('tr.is-selected').length, 5, 'shift-clicking another row selects it and all rows between');

    await click(middleRow);
    assert.equal(findAll('tr.is-selected').length, 4, 'clicking a selected row deselects it without affecting other selected rows');

    await click(middleRow);
    assert.equal(findAll('tr.is-selected').length, 5, 'clicking a deselected row selects it without affecting other selected rows');
  });
  test('save fails on invalid duration', async function(assert) {
    assert.expect(2);
    const school = this.server.create('school');
    const program = this.server.create('program', { school });
    const report = this.server.create('curriculum-inventory-report', {
      year: '2016',
      program,
    });

    const reportModel = await run(() => this.owner.lookup('service:store').find('curriculum-inventory-report', report.id));
    this.set('report', reportModel);
    await render(hbs`{{new-curriculum-inventory-sequence-block report=report}}`);
    await fillIn('.title input', 'Foo Bar');
    await fillIn('.description textarea', 'Lorem Ipsum');
    let startDateInput = find('.start-date input');
    let endDateInput = find('.end-date input');
    let interactor = openDatepicker(startDateInput);
    interactor.selectDate(moment('2016-11-12').toDate());
    interactor = openDatepicker(endDateInput);
    interactor.selectDate(moment('2016-12-30').toDate());
    assert.dom('.validation-error-message').doesNotExist('Initially, no validation error is shown.');
    await fillIn('.duration input', 'WRONG');
    await click('button.done');
    assert.dom('.validation-error-message').exists({ count: 1 }, 'Validation error shows.');
  });
Example #6
0
  test('it functions as expected', async function(assert) {
    this.setProperties({
      exportPolicy: {
        containsUserGeneratedContent: false,
        containsUserActionGeneratedContent: false,
        containsUserDerivedContent: false
      },
      isEditing: false,
      toggleEditing: editingMode => this.set('isEditing', editingMode),
      onSaveExportPolicy: exportPolicy => {
        assert.equal(exportPolicy.containsUserGeneratedContent, true, 'Sends the correct export policy object');
      }
    });

    await render(hbs`{{datasets/compliance/export-policy
                       exportPolicy=exportPolicy
                       isEditing=isEditing
                       toggleEditing=toggleEditing
                       onSaveExportPolicy=onSaveExportPolicy}}`);

    assert.expect(7);
    assert.ok(this.element, 'Still renders without errors');
    assert.equal(this.get('isEditing'), false, 'Base case for is editing test');
    assert.notOk(find(actionBar), 'Action bar does not exist without editing mode');

    await click(editButton);

    assert.equal(this.get('isEditing'), true, 'Edit button works');
    assert.ok(find(actionBar), 'Action bar now exists with editing mode');
    assert.ok(find(`${UGCRadioButton}`), 'Edit radio butotn for UGC exists');

    await click(`${UGCRadioButton}`);
    await click(saveButton);
  });
  test('it exposes default swiper navigation controls to `navigation=true`', async function(assert) {
    await render(hbs`
      {{#swiper-container navigation=true}}
        {{swiper-slide}}
        {{swiper-slide}}
        {{swiper-slide}}
      {{/swiper-container}}
    `);

    assert.ok(find('.swiper-button-next'), 'rendered nav next button');
    assert.ok(find('.swiper-button-prev'), 'rendered nav prev button');

    let slides = Array.from(findAll('.swiper-slide'));

    await click('.swiper-button-next');

    assert.ok(
      slides[1].classList.contains('swiper-slide-active'),
      'next button click handled'
    );

    await click('.swiper-button-prev');

    assert.ok(
      slides[0].classList.contains('swiper-slide-active'),
      'previous button click handled'
    );
  });
  test('save with date range and a zero duration', async function(assert) {
    assert.expect(2);
    const school = this.server.create('school');
    const program = this.server.create('program', { school });
    const report = this.server.create('curriculum-inventory-report', {
      year: '2016',
      program,
    });

    const reportModel = await run(() => this.owner.lookup('service:store').find('curriculum-inventory-report', report.id));
    this.set('report', reportModel);

    this.set('saveBlock', () => {
      return resolve();
    });
    await render(hbs`{{new-curriculum-inventory-sequence-block report=report save=(action saveBlock)}}`);
    await fillIn('.title input', 'Foo Bar');
    await fillIn('.description textarea', 'Lorem Ipsum');
    let startDateInput = find('.start-date input');
    let endDateInput = find('.end-date input');
    let interactor = openDatepicker(startDateInput);
    interactor.selectDate(moment('2016-11-12').toDate());
    interactor = openDatepicker(endDateInput);
    interactor.selectDate(moment('2016-12-30').toDate());
    await fillIn('.duration input', '0');
    await click('button.done');

    const blocks = await run(() => this.owner.lookup('service:store').findAll('curriculum-inventory-sequence-block'));
    assert.equal(blocks.length, 1);
    const newBlock = blocks.objectAt(0);
    assert.equal(newBlock.duration, 0, 'correcrt duration.');

  });
  test('clear dates', async function(assert) {
    assert.expect(4);
    const newStartDate = moment('2016-01-12');
    const newEndDate = moment('2017-02-22');

    const school = this.server.create('school');
    const program = this.server.create('program', { school });
    const report = this.server.create('curriculum-inventory-report', {
      year: '2016',
      program,
    });

    const reportModel = await run(() => this.owner.lookup('service:store').find('curriculum-inventory-report', report.id));
    this.set('report', reportModel);

    await render(hbs`{{new-curriculum-inventory-sequence-block report=report}}`);
    let startDateInput = find('.start-date input');
    let endDateInput = find('.end-date input');
    let interactor = openDatepicker(startDateInput);
    interactor.selectDate(newStartDate.toDate());
    interactor = openDatepicker(endDateInput);
    interactor.selectDate(newEndDate.toDate());
    assert.equal(newStartDate.format('M/D/YYYY'), startDateInput.value, 'Start date is set');
    assert.equal(newEndDate.format('M/D/YYYY'), endDateInput.value, 'End date is set');
    await click('.clear-dates button');
    assert.equal(startDateInput.value, '', 'Start date input has been cleared.');
    assert.equal(endDateInput.value, '', 'End date input has been cleared.');
  });
Example #10
0
  test('confirmation of remove message', async function (assert) {
    this.user.update({administeredSchools: [this.school]});

    this.server.createList('user', 5);
    this.server.create('program', {
      schoolId: 1,
    });
    this.server.create('programYear', {
      programId: 1,
    });
    this.server.create('cohort', {
      programYearId: 1,
    });
    this.server.create('learnerGroup', {
      cohortId: 1,
    });
    this.server.createList('learnerGroup', 2, {
      parentId: 1
    });
    this.server.createList('offering', 2, {learnerGroupIds: [1]});
    assert.expect(5);
    await visit('/learnergroups');
    assert.equal(1, findAll('.list tbody tr').length);
    assert.equal(await getElementText(find(find('.list tbody tr:nth-of-type(1) td'))), getText('learnergroup 0'));
    await click('.list tbody tr:nth-of-type(1) td:nth-of-type(4) .remove');
    assert.dom('.list tbody tr').hasClass('confirm-removal');
    assert.dom(findAll('.list tbody tr')[1]).hasClass('confirm-removal');
    assert.equal(await getElementText(find(findAll('.list tbody tr')[1])), getText('Are you sure you want to delete this learner group, with 2 subgroups? This action cannot be undone. Yes Cancel'));
  });
  test('row expansion', async function(assert) {
    this.set('table', new Table(Columns, this.server.createList('user', 2)));
    this.set('canExpand', false);

    await render(hbs `
      {{#lt-body table=table sharedOptions=sharedOptions canSelect=false canExpand=canExpand multiRowExpansion=false as |b|}}
        {{#b.expanded-row}} Hello {{/b.expanded-row}}
      {{/lt-body}}
    `);

    let row = find('tr');

    assert.notOk(hasClass(row, 'is-expandable'));
    await click(row);
    assert.equal(findAll('tr.lt-expanded-row').length, 0);
    assert.equal(findAll('tbody > tr').length, 2);
    assert.notOk(find('tr.lt-expanded-row'));

    this.set('canExpand', true);

    assert.ok(hasClass(row, 'is-expandable'));
    await click(row);
    assert.equal(findAll('tr.lt-expanded-row').length, 1);
    assert.equal(findAll('tbody > tr').length, 3);
    assert.equal(row.nextElementSibling.textContent.trim(), 'Hello');

    let allRows = findAll('tr');
    row = allRows[allRows.length - 1];
    assert.ok(hasClass(row, 'is-expandable'));
    await click(row);
    assert.equal(findAll('tr.lt-expanded-row').length, 1);
    assert.equal(findAll('tbody > tr').length, 3);
    assert.equal(row.nextElementSibling.textContent.trim(), 'Hello');
  });
Example #12
0
  test('populated learner groups are not deletable', async function (assert) {
    this.user.update({administeredSchools: [this.school]});

    this.server.createList('user', 5);
    this.server.create('program', {
      schoolId: 1,
    });
    this.server.create('programYear', {
      programId: 1,
    });
    this.server.create('cohort', {
      programYearId: 1,
    });
    this.server.create('learnerGroup', {
      cohortId: 1,
      userIds: [2, 3, 4],
    });
    this.server.createList('offering', 2, {learnerGroupIds: [1]});

    assert.expect(3);
    await visit('/learnergroups');
    assert.equal(1, findAll('.list tbody tr').length);
    assert.equal(await getElementText(find(find('.list tbody tr:nth-of-type(1) td'))), getText('learnergroup 0'));
    assert.notOk(findAll('.list tbody tr:nth-of-type(1) td:nth-of-type(4) .remove').length, 'No delete action is available');
  });
  test('save with defaults', async function(assert) {
    assert.expect(17);
    const school = this.server.create('school');
    const academicLevels = this.server.createList('curriculum-inventory-academic-level', 10);
    const program = this.server.create('program', { school });
    const report = this.server.create('curriculum-inventory-report', {
      academicLevels,
      year: '2016',
      program,
    });

    let newTitle = 'new sequence block';
    let newDescription = 'lorem ipsum';
    let newStartDate = moment('2016-01-05');
    let newEndDate = moment('2016-02-12');
    const reportModel = await run(() => this.owner.lookup('service:store').find('curriculum-inventory-report', report.id));

    this.set('report', reportModel);
    this.set('saveBlock', (block) => {
      assert.ok(block, 'Sequence block gets passed to saveBlock action.');
      return resolve();
    });

    await render(hbs`{{new-curriculum-inventory-sequence-block report=report save=(action saveBlock)}}`);
    await fillIn('.title input', newTitle);
    await fillIn('.description textarea', newDescription);
    let interactor = openDatepicker(find('.start-date input'));
    interactor.selectDate(newStartDate.toDate());
    interactor = openDatepicker(find('.end-date input'));
    interactor.selectDate(newEndDate.toDate());
    await click('button.done');

    const blocks = await run(() => this.owner.lookup('service:store').findAll('curriculum-inventory-sequence-block'));
    assert.equal(blocks.length, 1);
    const newBlock = blocks.objectAt(0);
    assert.equal(newBlock.title, newTitle, 'Given title gets passed.');
    assert.equal(newBlock.description, newDescription, 'Given description gets passed.');
    assert.equal(newBlock.belongsTo('parent').id(), null, 'No parent gets passed for new top-level block.');
    assert.equal(newBlock.belongsTo('academicLevel').id(), academicLevels[0].id, 'First academic level gets passed by default.');
    assert.equal(newBlock.required, 1, '"Required" is passed by default.');
    assert.equal(newBlock.track, false, 'FALSE is passed for "Is Track?" by default.');
    assert.equal(newBlock.orderInSequence, 0, 'order in sequence is zero for top-level blocks.');
    assert.equal(newBlock.childSequenceOrder, 1, 'Child sequence order defaults to "ordered".');
    assert.equal(
      moment(newBlock.startDate).format('YYYY-MM-DD'),
      newStartDate.format('YYYY-MM-DD'),
      'Given start date gets passed.'
    );
    assert.equal(
      moment(newBlock.endDate).format('YYYY-MM-DD'),
      newEndDate.format('YYYY-MM-DD'),
      'Given end date gets passed.'
    );
    assert.equal(newBlock.minimum, 0, 'Minimum defaults to zero.');
    assert.equal(newBlock.minimum, 0, 'Maximum defaults to zero');
    assert.equal(newBlock.belongsTo('course').id(), null, 'No course gets selected/passed by default.');
    assert.equal(newBlock.duration, 0, 'Duration defaults to zero');
    assert.equal(newBlock.belongsTo('report').id(), report.id, 'Given report gets passed.');
  });
Example #14
0
  test('it renders', async function(assert) {
    assert.expect(33);
    this.server.create('school', { title: 'first' });
    const school2 = this.server.create('school', { title: 'second' });
    this.server.create('school', { title: 'third' });

    const mockUser = EmberObject.create({
      school: resolve(school2)
    });

    const currentUserMock = Service.extend({
      model: resolve(mockUser)
    });
    this.owner.register('service:current-user', currentUserMock);


    this.set('close', ()=>{});
    await render(hbs`{{new-myreport close=(action close)}}`);
    const title = '.title';
    const schools = '[data-test-school] select';
    const subjects = '[data-test-subject] select';

    const schoolSelect = find(schools);
    assert.dom(title).hasText('New Report');
    assert.ok(schoolSelect.options[0].value, "null");
    assert.ok(schoolSelect.options[0].textContent.includes('All Schools'));
    assert.ok(schoolSelect.options[1].value, "1");
    assert.ok(schoolSelect.options[1].textContent.includes('first'));
    assert.ok(schoolSelect.options[2].value, "2");
    assert.ok(schoolSelect.options[2].textContent.includes('second'));
    assert.ok(schoolSelect.options[3].value, "3");
    assert.ok(schoolSelect.options[3].textContent.includes('third'));
    assert.equal(schoolSelect.options[schoolSelect.selectedIndex].value, 2, 'primary school is selected');

    const subjectSelect = find(subjects);
    assert.ok(subjectSelect.options[0].value, "course");
    assert.ok(subjectSelect.options[0].textContent.includes('Courses'));
    assert.ok(subjectSelect.options[1].value, "session");
    assert.ok(subjectSelect.options[1].textContent.includes('Sessions'));
    assert.ok(subjectSelect.options[2].value, "program");
    assert.ok(subjectSelect.options[2].textContent.includes('Programs'));
    assert.ok(subjectSelect.options[3].value, "program year");
    assert.ok(subjectSelect.options[3].textContent.includes('Program Years'));
    assert.ok(subjectSelect.options[4].value, "instructor");
    assert.ok(subjectSelect.options[4].textContent.includes('Instructors'));
    assert.ok(subjectSelect.options[5].value, "instructor group");
    assert.ok(subjectSelect.options[5].textContent.includes('Instructor Groups'));
    assert.ok(subjectSelect.options[6].value, "learning material");
    assert.ok(subjectSelect.options[6].textContent.includes('Learning Materials'));
    assert.ok(subjectSelect.options[7].value, "competency");
    assert.ok(subjectSelect.options[7].textContent.includes('Competencies'));
    assert.ok(subjectSelect.options[8].value, "mesh term");
    assert.ok(subjectSelect.options[8].textContent.includes('MeSH Terms'));
    assert.ok(subjectSelect.options[9].value, "term");
    assert.ok(subjectSelect.options[9].textContent.includes('Terms'));
    assert.ok(subjectSelect.options[10].value, "session type");
    assert.ok(subjectSelect.options[10].textContent.includes('Session Types'));
    assert.equal(subjectSelect.options[subjectSelect.selectedIndex].value, 'course', 'courses is selected');
  });
    it('displays invalid file type error', async function () {
        stubFailedUpload(server, 415, 'UnsupportedMediaTypeError');
        await render(hbs`{{gh-file-uploader url=uploadUrl}}`);
        await fileUpload('input[type="file"]', ['test'], {name: 'test.csv'});

        expect(findAll('.failed').length, 'error message is displayed').to.equal(1);
        expect(find('.failed').textContent).to.match(/The file type you uploaded is not supported/);
        expect(findAll('.gh-btn-green').length, 'reset button is displayed').to.equal(1);
        expect(find('.gh-btn-green').textContent).to.equal('Try Again');
    });
    it('has no success/error class by default', async function () {
        await render(hbs`
            {{#gh-validation-status-container class="gh-test" property="name" errors=testObject.errors hasValidated=testObject.hasValidated}}
            {{/gh-validation-status-container}}
        `);

        expect(find('.gh-test')).to.exist;
        expect(find('.gh-test')).to.not.have.class('success');
        expect(find('.gh-test')).to.not.have.class('error');
    });
Example #17
0
 test('save no competency', async function(assert) {
   this.user.update({ administeredSchools: [this.school] });
   assert.expect(1);
   await visit(url);
   await click('.programyear-objective-list tbody tr:nth-of-type(1) td:nth-of-type(3) .link');
   let objectiveManager = find('.objective-manage-competency')[0];
   await click(find('.parent-picker .clickable'), objectiveManager);
   await click('.detail-objectives button.bigadd');
   assert.equal(await getElementText(find(findAll('.programyear-objective-list tbody tr td')[2])), getText('Add New'));
 });
  test('Highlighting Views on hover', async function t(assert) {
    let name, message;
    port.reopen({
      send(n, m) {
        name = n;
        message = m;
      }
    });

    await visit('/simple');

    run(() => port.trigger('view:inspectViews', { inspect: true }));
    await wait();

    await triggerEvent('.application', 'mousemove');

    let previewDiv = find('[data-label=preview-div]');

    assert.ok(isVisible(previewDiv));
    assert.dom('[data-label=layer-component]').doesNotExist('Component layer not shown on outlet views');
    assert.dom(previewDiv.querySelector('[data-label=layer-controller]')).hasText('App.ApplicationController');
    assert.dom(previewDiv.querySelector('[data-label=layer-model]')).hasText('Application model');

    let layerDiv = find('[data-label=layer-div]');
    await triggerEvent(layerDiv, 'mouseup');

    assert.ok(isVisible(layerDiv));
    assert.dom(layerDiv.querySelector('[data-label=layer-model]')).hasText('Application model');
    await click(layerDiv.querySelector('[data-label=layer-controller]'));

    let controller = this.owner.lookup('controller:application');
    assert.equal(name, 'objectInspector:updateObject');
    assert.equal(controller.toString(), message.name);
    name = null;
    message = null;

    await click(layerDiv.querySelector('[data-label=layer-model]'));

    assert.equal(name, 'objectInspector:updateObject');
    assert.equal(message.name, 'Application model');
    await click('[data-label=layer-close]');

    assert.notOk(isVisible(layerDiv));

    run(() => port.trigger('view:inspectViews', { inspect: true }));
    await wait();

    await triggerEvent('.simple-input', 'mousemove');

    previewDiv = find('[data-label=preview-div]');
    assert.ok(isVisible(previewDiv));
    assert.ok(find('[data-label=layer-component]').textContent.trim(), 'Ember.TextField');
    assert.notOk(previewDiv.querySelector('[data-label=layer-controller]'));
    assert.notOk(previewDiv.querySelector('[data-label=layer-model]'));
  });
  test('it renders', async function(assert) {
    await render(hbs`{{swiper-container}}`);
    assert.equal(find('*').textContent.trim(), '');

    await render(hbs`
      {{#swiper-container}}
        template block text
      {{/swiper-container}}
    `);
    assert.equal(find('*').textContent.trim(), 'template block text');
  });
    it('calculates image width/height', async function () {
        await render(hbs`{{gh-unsplash-photo photo=photo}}`);

        expect(
            find('[data-test-unsplash-photo-image]').attributes.width.value
        ).to.equal('1200');

        expect(
            find('[data-test-unsplash-photo-image]').attributes.height.value
        ).to.equal('800');
    });
        it('handles ember-ajax HTML response', async function () {
            this.server.del('/themes/foo/', htmlErrorResponse);

            await visit('/settings/design');
            await click('[data-test-theme-id="foo"] [data-test-theme-delete-button]');
            await click('.fullscreen-modal [data-test-delete-button]');

            expect(findAll('.gh-alert').length).to.equal(1);
            expect(find('.gh-alert').textContent).to.not.match(/html>/);
            expect(find('.gh-alert').textContent).to.match(/Request was rejected due to server error/);
        });
Example #22
0
 test('es2015 class based components dispatch & render state from redux', async function(assert) {
   await visit('/clazz');
   assert.equal(currentURL(), '/clazz');
   assert.equal(find('.clazz-state').textContent, '0');
   assert.equal(find('.clazz-up').textContent, 'up');
   assert.equal(find('.clazz-color').textContent, 'orange');
   await click('.clazz-up');
   assert.equal(currentURL(), '/clazz');
   assert.equal(find('.clazz-state').textContent, '1');
   assert.equal(find('.clazz-color').textContent, 'orange');
 });
  test('it carries ciphertext value over to decrypt', async function(assert) {
    const plaintext = 'not so secret';
    await doEncrypt.call(this, assert, ['decrypt']);

    this.set('storeService.keyActionReturnVal', { plaintext });
    this.set('selectedAction', 'decrypt');
    assert.equal(find('#ciphertext').value, 'secret', 'keeps ciphertext value');

    await click('button[type="submit"]');
    assert.equal(find('#plaintext').value, plaintext, 'renders decrypted value');
  });
    it('displays char count for text fields', async function () {
        await render(hbs`
            {{gh-tag-settings-form tag=tag setProperty=(action setProperty)}}
        `);

        let descriptionFormGroup = find('textarea[name="description"]').closest('.form-group');
        expect(descriptionFormGroup.querySelector('.word-count'), 'description char count').to.have.trimmed.text('12');

        let metaDescriptionFormGroup = find('textarea[name="metaDescription"]').closest('.form-group');
        expect(metaDescriptionFormGroup.querySelector('.word-count'), 'description char count').to.have.trimmed.text('16');
    });
  test('validation', async function(assert) {
    // validation is based on validation of every option fragment
    // which validates according to poll model it belongs to
    // therefore each option needs to be pushed to poll model to have it as
    // it's owner
    let poll = this.store.createRecord('poll', {
      isFindADate: true,
      isMakeAPoll: false
    });
    poll.options.pushObjects([
      { title: '2015-01-01' },
      { title: '2015-02-02' }
    ]);
    this.set('options', poll.options);

    await render(hbs`{{create-options-datetime dates=options}}`);
    assert.ok(
      findAll('.has-error').length === 0 && findAll('.has-success').length === 0,
      'does not show a validation error before user interaction'
    );

    await fillIn('[data-test-day="2015-01-01"] .form-group input', '10:');
    await blur('[data-test-day="2015-01-01"] .form-group input');
    assert.ok(
      find('[data-test-day="2015-01-01"] .form-group').classList.contains('has-error') ||
      // browsers with input type time support prevent non time input
      find('[data-test-day="2015-01-01"] .form-group input').value === '',
      'shows error after invalid input or prevents invalid input'
    );

    // simulate unique violation
    await click('[data-test-day="2015-01-01"] .add');
    await fillIn(findAll('[data-test-day="2015-01-01"]')[0].querySelector('input'), '10:00');
    await fillIn(findAll('[data-test-day="2015-01-01"]')[1].querySelector('input'), '10:00');
    await fillIn('[data-test-day="2015-02-02"] .form-group input', '10:00');
    await triggerEvent('form', 'submit');
    assert.dom(findAll('[data-test-day="2015-01-01"]')[0].querySelector('.form-group')).hasClass('has-success',
      'first time shows validation success'
    );
    assert.dom(findAll('[data-test-day="2015-01-01"]')[1].querySelector('.form-group')).hasClass('has-error',
      'same time for same day shows validation error'
    );
    assert.dom('[data-test-day="2015-02-02"] .form-group').hasClass('has-success',
      'same time for different day shows validation success'
    );

    // label reflects validation state for all times of this day
    assert.dom(find('[data-test-day="2015-01-01"]')).hasClass('label-has-error',
      'label reflects validation state for all times (error)'
    );
    assert.dom('[data-test-day="2015-02-02"]').hasClass('label-has-success',
      'label reflects validation state for all times (success)'
    );
  });
  test('it removes a row', async function(assert) {
    this.set('inputValue', ['foo', 'bar']);
    this.set('onChange', function(val) {
      assert.equal(val, 'bar', 'calls onChange with expected value');
    });
    await render(hbs`{{string-list inputValue=inputValue onChange=(action onChange)}}`);

    await click('[data-test-string-list-row="0"] [data-test-string-list-button="delete"]');
    assert.equal(findAll('[data-test-string-list-input]').length, 2, 'renders 2 inputs');
    assert.equal(find('[data-test-string-list-input="0"]').value, 'bar');
    assert.equal(find('[data-test-string-list-input="1"]').value, '');
  });
        it('handles Ember Data HTML response', async function () {
            this.server.put('/posts/1/', htmlErrorResponse);
            this.server.create('post');

            await visit('/editor/post/1');
            await click('[data-test-publishmenu-trigger]');
            await click('[data-test-publishmenu-save]');

            expect(findAll('.gh-alert').length).to.equal(1);
            expect(find('.gh-alert').textContent).to.not.match(/html>/);
            expect(find('.gh-alert').textContent).to.match(/Request was rejected due to server error/);
        });
    it('renders main settings', async function () {
        await render(hbs`
            {{gh-tag-settings-form tag=tag setProperty=(action setProperty)}}
        `);

        expect(findAll('.gh-image-uploader').length, 'displays image uploader').to.equal(1);
        expect(find('input[name="name"]').value, 'name field value').to.equal('Test');
        expect(find('input[name="slug"]').value, 'slug field value').to.equal('test');
        expect(find('textarea[name="description"]').value, 'description field value').to.equal('Description.');
        expect(find('input[name="metaTitle"]').value, 'metaTitle field value').to.equal('Meta Title');
        expect(find('textarea[name="metaDescription"]').value, 'metaDescription field value').to.equal('Meta description');
    });
  test('it applies custom navigation hash of control selectors', async function(assert) {
    await render(hbs`
      {{#swiper-container navigation=(hash nextEl=".is-next" prevEl=".is-last")}}
        {{swiper-slide}}
        {{swiper-slide}}
        {{swiper-slide}}
      {{/swiper-container}}
    `);

    assert.ok(find('.is-next'), 'rendered custom nav next button');
    assert.ok(find('.is-last'), 'rendered custom nav prev button');
  });
 test('it detects changes to value after encoding', async function(assert) {
   this.set('value', btoa('value'));
   await render(hbs`{{b64-toggle value=value initialEncoding='base64'}}`);
   assert.ok(find('button').textContent.includes('Decode'), 'renders as on when in b64 mode');
   this.set('value', btoa('value') + '=');
   assert.ok(find('button').textContent.includes('Encode'), 'toggles off since value has changed');
   this.set('value', btoa('value'));
   assert.ok(
     find('button').textContent.includes('Decode'),
     'toggles on since value is equal to the original'
   );
 });