<repo_name>jesscjess/TDD-final-project<file_sep>/test/routes/create-video-test.js
// Step 1 create the default files for this level for testing
// Step 2 have examples show what you can do with app to make simple tests
// 
// Can explain this in docs
// 
// Create easy way to add tests that provide specific information
// 
// should we look into chai-webdriver or is chai enough?? 
const { assert } = require('chai');
const request = require('supertest');
const { jsdom } = require('jsdom');

const app = require('../../app');
const Video = require('../../models/video');

const { parseTextFromHTML, buildItemObject } = require('../test-helper-funcs');
const { connectDatabase, disconnectDatabase } = require('../db-helper-funcs');


describe('Server path: /videos/create ->', () => {

  beforeEach(connectDatabase);

  afterEach(disconnectDatabase);

  describe('POST ->', () => {
    it('create new video', async () => {
      const newVideo = buildItemObject();
      const response = await request(app)
        .post('/videos/create')
        .type('form')
        .send(newVideo);

        const createdItem = await Video.findOne(newVideo);
        assert.equal(response.status, 302);
        assert.isOk(createdItem, 'Looks like item was not created successfully in the database');
    });

    it('cannot create video with NO title', async () => {
      const newVideo = buildItemObject();
      newVideo.title = '';
      const response = await request(app)
        .post('/videos/create')
        .type('form')
        .send(newVideo);

        assert.deepEqual(await Video.find({}), []);
        assert.equal(response.status, 400);
        assert.include(parseTextFromHTML(response.text, 'form'), 'Path `title` is required.');
        assert.include(parseTextFromHTML(response.text, 'form'), newVideo.description);
    });

  });

});
<file_sep>/test/features/user-visits-create-page-test.js
const {assert} = require('chai');

const {buildItemObject} = require('../test-helper-funcs')

describe('User visits create page ->', () => {
  describe('creates new video ->', () => {
    it('sees new video on main page', () => {
      browser.url('/videos/create');
      const newItem = buildItemObject()

      browser.setValue('#title-input', newItem.title);
      browser.setValue('#description-input', newItem.description);
      browser.click('#submit-button')

      assert.include(browser.getText('body'), newItem.title);
      assert.include(browser.getText('body'), newItem.description);
      
    });
  });
});<file_sep>/test/test-helper-funcs.js
const {jsdom} = require('jsdom');

const Video = require('../models/video');

const buildItemObject = (options = {}) => {
  const title = options.title || 'New video I made up';
  const description = options.description || 'This is a video I made up durrr';
  const url = options.url || 'https://www.youtube.com/embed/UcfOIfa5kvE';
  return {title, description, url};
};

// Add a sample Item object to mongodb
const seedItemToDatabase = async (options = {}) => {
  const item = await Video.create(buildItemObject(options));
  return item;
};

// extract text from an Element by selector.
const parseTextFromHTML = (htmlAsString, selector) => {
  const selectedElement = jsdom(htmlAsString).querySelector(selector);
  if (selectedElement !== null) {
    return selectedElement.textContent;
  } else {
    throw new Error(`No element with selector ${selector} found in HTML string`);
  }
};

module.exports = {
  buildItemObject,
  seedItemToDatabase,
  parseTextFromHTML
};<file_sep>/test/models/video-test.js
const Video = require('../../models/video')
const { assert } = require('chai');
const { mongoose, databaseUrl, options } = require('../../database');
const {connectDatabase, disconnectDatabase} = require('../db-helper-funcs');

describe('Video Model ->', () => {

  beforeEach(connectDatabase);
  afterEach(disconnectDatabase);

  describe('#Title ->', () => {
    it('is a String', () => {
      const integerTitle = 9;
      const video = new Video({ title: integerTitle });

      assert.strictEqual(video.title, integerTitle.toString());
    })
  });
  describe('#Description ->', () => {
    it('is a String', () => {
      const integerDescription = 9;
      const video = new Video({ description: integerDescription });

      assert.strictEqual(video.description, integerDescription.toString());
    })
  });

  // Question: is it better to not test if something is required here so that I can test it with the error message ar the routes level? 
});
<file_sep>/test/features/user-visits-landing-page-test.js
const {assert} = require('chai');

const { parseTextFromHTML, seedItemToDatabase, buildItemObject } = require('../test-helper-funcs');

describe('User hits main page ->', () => {
  describe('with no videos added yet ->', () => {
    it('page has no items', () => {
      browser.url('/videos');
      assert.equal(browser.getText('#videos-container'), '')
    });
  });

  describe('with existing videos ->', () => {
    it('page shows iframe',  () => {
      browser.url('/videos/create');
      const newVideo = buildItemObject();

      browser.setValue('#title-input', newVideo.title);
      browser.setValue('#description-input', newVideo.description);
      browser.setValue('#url-input', newVideo.url);

      browser.url('/');

      assert.include(browser.getText('body'), 'iframe');

    });
  });

  describe('can navigate ->', () => {
    it('to videos/create', () => {
      browser.url('/videos');

      // browser.click('a[href="/videos/create]') -> not wokring :/
      browser.click('a')
      assert.include(browser.getText('body'), 'Add Video');

    });
  });
});
<file_sep>/test/routes/single-video-test.js
const { assert } = require('chai');
const request = require('supertest');

const app = require('../../app');

const { parseTextFromHTML, seedItemToDatabase } = require('../test-helper-funcs');
const { connectDatabase, disconnectDatabase } = require('../db-helper-funcs');

describe('Server path: /video/:id', () => {
  beforeEach(connectDatabase);

  afterEach(disconnectDatabase);

  // Write your test blocks below:
  describe('GET', () => {
    it('correct video rendered', async () => {
      const newVideo = await seedItemToDatabase();
      const videoUrl = '/video/' + newVideo._id.toString();

      const response = await request(app)
        .get(videoUrl);

      assert.equal(response.status, 200);
      assert.include(parseTextFromHTML(response.text, '#item-title'), newVideo.title);
      assert.include(parseTextFromHTML(response.text, '#item-description'), newVideo.description);
    })
  })

});<file_sep>/README.md
# TDD-final-project
