diff --git a/src/cookie-content.hbs b/src/cookie-content.hbs new file mode 100644 index 0000000..c350ee4 --- /dev/null +++ b/src/cookie-content.hbs @@ -0,0 +1,53 @@ + + +
+ Поиск cookie: +
+
+
+ Добавить cookie:
+
+
+ +
+
+
+ Доступные cookie: + + + + + + + + + + + +
имязначениеудалить
+
diff --git a/src/cookie.hbs b/src/cookie.hbs new file mode 100644 index 0000000..c882810 --- /dev/null +++ b/src/cookie.hbs @@ -0,0 +1,12 @@ + + + + + {{htmlWebpackPlugin.options.title}} + + +
+ {{> "./cookie-content.hbs"}} +
+ + diff --git a/src/cookie.js b/src/cookie.js new file mode 100644 index 0000000..031b250 --- /dev/null +++ b/src/cookie.js @@ -0,0 +1,144 @@ +/* + ДЗ 7 - Создать редактор cookie с возможностью фильтрации + + 7.1: На странице должна быть таблица со списком имеющихся cookie. Таблица должна иметь следующие столбцы: + - имя + - значение + - удалить (при нажатии на кнопку, выбранная cookie удаляется из браузера и таблицы) + + 7.2: На странице должна быть форма для добавления новой cookie. Форма должна содержать следующие поля: + - имя + - значение + - добавить (при нажатии на кнопку, в браузер и таблицу добавляется новая cookie с указанным именем и значением) + + Если добавляется cookie с именем уже существующей cookie, то ее значение в браузере и таблице должно быть обновлено + + 7.3: На странице должно быть текстовое поле для фильтрации cookie + В таблице должны быть только те cookie, в имени или значении которых, хотя бы частично, есть введенное значение + Если в поле фильтра пусто, то должны выводиться все доступные cookie + Если добавляемая cookie не соответсвует фильтру, то она должна быть добавлена только в браузер, но не в таблицу + Если добавляется cookie, с именем уже существующей cookie и ее новое значение не соответствует фильтру, + то ее значение должно быть обновлено в браузере, а из таблицы cookie должна быть удалена + + Запрещено использовать сторонние библиотеки. Разрешено пользоваться только тем, что встроено в браузер + */ + +/* + homeworkContainer - это контейнер для всех ваших домашних заданий + Если вы создаете новые html-элементы и добавляете их на страницу, то добавляйте их только в этот контейнер + + Пример: + const newDiv = document.createElement('div'); + homeworkContainer.appendChild(newDiv); + */ +const homeworkContainer = document.querySelector('#homework-container'); +// текстовое поле для фильтрации cookie +const filterNameInput = homeworkContainer.querySelector('#filter-name-input'); +// текстовое поле с именем cookie +const addNameInput = homeworkContainer.querySelector('#add-name-input'); +// текстовое поле со значением cookie +const addValueInput = homeworkContainer.querySelector('#add-value-input'); +// кнопка "добавить cookie" +const addButton = homeworkContainer.querySelector('#add-button'); +// таблица со списком cookie +const listTable = homeworkContainer.querySelector('#list-table tbody'); + +let cookies = {}; + +function getCookies() { + let allCookies = document.cookie; + + if (allCookies.length === 0) { + return cookies; + } + + allCookies.split('; ').forEach(cookie => { + let pair = cookie.split('='); + + cookies[pair[0]] = pair[1]; + }); + + return cookies; +} + +function deleteCookie(name) { + delete cookies[name]; + + document.cookie = name + '=; Max-Age=-1;'; +} + +function displayCookie(cookieList = cookies) { + const fragment = document.createDocumentFragment(); + + listTable.innerHTML = ''; + + for (let [name, value] of Object.entries(cookieList)) { + const tr = document.createElement('tr'); + const tdName = document.createElement('td'); + const tdValue = document.createElement('td'); + + tdName.innerText = name; + tdValue.innerText = value.toString(); + tr.appendChild(tdName); + tr.appendChild(tdValue); + + const tdDelBtn = document.createElement('td'); + const delBtn = document.createElement('button'); + + delBtn.innerText = 'X'; + tdDelBtn.style.textAlign = 'center'; + + delBtn.addEventListener('click', () => { + tr.remove(); + deleteCookie(name, value); + }); + + tdDelBtn.appendChild(delBtn); + tr.appendChild(tdDelBtn); + fragment.appendChild(tr); + } + + listTable.appendChild(fragment); +} + +function isMatching(name, value, chunk) { + const reg = new RegExp(chunk); + + return ((name.search(reg) !== -1) || (value.search(reg) !== -1)); +} + +function filterCookie(filterValue) { + if (filterValue.length === 0) { + displayCookie(); + } else { + let filteredCookies = {}; + + Object.entries(cookies).forEach(([name, value]) => { + if (isMatching(name, value, filterValue)) { + filteredCookies[name] = value; + } + }); + + displayCookie(filteredCookies); + } +} + +filterNameInput.addEventListener('keyup', function () { + // здесь можно обработать нажатия на клавиши внутри текстового поля для фильтрации cookie + filterCookie(filterNameInput.value); +}); + +addButton.addEventListener('click', () => { + // здесь можно обработать нажатие на кнопку "добавить cookie" + if (addNameInput.value.length !== 0 && addValueInput.value.length !== 0) { + document.cookie = `${addNameInput.value}=${addValueInput.value}`; + getCookies(); + filterCookie(filterNameInput.value); + } +}); + +document.addEventListener('DOMContentLoaded', () => { + let existingCookies = getCookies(); + + displayCookie(existingCookies); +}); \ No newline at end of file diff --git a/src/index.js b/src/index.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/cookie.js b/test/cookie.js new file mode 100644 index 0000000..0a48c05 --- /dev/null +++ b/test/cookie.js @@ -0,0 +1,266 @@ +import assert from 'assert'; +let template = require('../src/cookie-content.hbs'); + +function getCookies() { + return document.cookie + .split('; ') + .filter(Boolean) + .map(cookie => cookie.match(/^([^=]+)=(.+)/)) + .reduce((obj, [, name, value]) => { + obj[name] = value; + + return obj; + }, {}); +} + +describe('ДЗ 7.2 - Cookie editor', () => { + let homeworkContainer = document.createElement('div'); + let filterNameInput; + let addNameInput; + let addValueInput; + let addButton; + let listTable; + + homeworkContainer.id = 'homework-container'; + homeworkContainer.innerHTML = template(); + document.body.appendChild(homeworkContainer); + require('../src/cookie'); + + describe('Интеграционное тестирование', () => { + beforeEach(() => { + let oldCookies = getCookies(); + + Object.keys(oldCookies).forEach(cookie => document.cookie = `${cookie}=;expires=${new Date(0)}`); + + if (listTable) { + listTable.innerHTML = ''; + } + }); + + it('на старнице должны быть элементы с нужными id', () => { + filterNameInput = homeworkContainer.querySelector('#filter-name-input'); + addNameInput = homeworkContainer.querySelector('#add-name-input'); + addValueInput = homeworkContainer.querySelector('#add-value-input'); + addButton = homeworkContainer.querySelector('#add-button'); + listTable = homeworkContainer.querySelector('#list-table tbody'); + + assert(filterNameInput !== null, 'элемент не найден'); + assert(filterNameInput instanceof Element, 'id элемента должен быть filter-name-input'); + assert(addNameInput !== null, 'элемент не найден'); + assert(addNameInput instanceof Element, 'id элемента должен быть add-name-input'); + assert(addValueInput !== null, 'элемент не найден'); + assert(addValueInput instanceof Element, 'id элемента должен быть add-value-input'); + assert(addButton !== null, 'элемент не найден'); + assert(addButton instanceof Element, 'id элемента должен быть add-button'); + assert(listTable !== null, 'элемент не найден'); + assert(listTable instanceof Element, 'id элемента должен быть list-table'); + }); + + it('cookie должны добавляться при нажатии на "добавить"', () => { + let cookies; + + addNameInput.value = 'test-cookie-name-1'; + addValueInput.value = 'test-cookie-value-1'; + addButton.click(); + + cookies = getCookies(); + assert(cookies.hasOwnProperty(addNameInput.value), 'cookie не добавлена в барузер'); + assert.equal(cookies[addNameInput.value], addValueInput.value, 'cookie не добавлена в барузер'); + assert.equal(listTable.children.length, 1, 'cookie не добавлена в таблицу'); + + addNameInput.value = 'test-cookie-name-2'; + addValueInput.value = 'test-cookie-value-2'; + addButton.click(); + + cookies = getCookies(); + assert(cookies.hasOwnProperty(addNameInput.value), 'cookie не добавлена в барузер'); + assert.equal(cookies[addNameInput.value], addValueInput.value, 'cookie не добавлена в барузер'); + assert.equal(listTable.children.length, 2, 'cookie не добавлена в таблицу'); + }); + + it('если при добавлении указано имя существующей cookie, то в таблице не должно быть дублей', () => { + let cookies; + + addNameInput.value = 'test-cookie-name-1'; + addValueInput.value = 'test-cookie-value-1'; + addButton.click(); + + addNameInput.value = 'test-cookie-name-2'; + addValueInput.value = 'test-cookie-value-2'; + addButton.click(); + + addNameInput.value = 'test-cookie-name-2'; + addValueInput.value = 'test-cookie-value-2'; + addButton.click(); + + cookies = getCookies(); + assert(cookies.hasOwnProperty(addNameInput.value), 'cookie не добавлена в барузер'); + assert.equal(cookies[addNameInput.value], addValueInput.value, 'не изменено значение cookie'); + assert.equal(listTable.children.length, 2, 'в таблице обнаружен дубль'); + }); + + it('если при добавлении указано имя существующей cookie, то в таблице должно быть изменено ее значение', () => { + let rows; + let changedRow; + + addNameInput.value = 'test-cookie-name-1'; + addValueInput.value = 'test-cookie-value-1'; + addButton.click(); + + addNameInput.value = 'test-cookie-name-2'; + addValueInput.value = 'test-cookie-value-2'; + addButton.click(); + + addNameInput.value = 'test-cookie-name-2'; + addValueInput.value = 'other-test-cookie-value-2'; + addButton.click(); + + rows = [...listTable.children]; + changedRow = rows.filter(row => row.children[1].textContent.trim() == 'other-test-cookie-value-2'); + assert.equal(changedRow.length, 1, 'новое значение для cookie не найдено в таблице'); + }); + + it('cookie должны удаляться при нажатии на "удалить"', () => { + let cookies; + let deleteButton; + + addNameInput.value = 'test-cookie-name-1'; + addValueInput.value = 'test-cookie-value-1'; + addButton.click(); + + addNameInput.value = 'test-cookie-name-2'; + addValueInput.value = 'test-cookie-value-2'; + addButton.click(); + + deleteButton = listTable.querySelector('button'); + + deleteButton.click(); + cookies = getCookies(); + assert.equal(Object.keys(cookies).length, 1, 'cookie не удалена из браузера'); + assert.equal(listTable.children.length, 1, 'cookie не удалена из таблицы'); + + deleteButton = listTable.querySelector('button'); + deleteButton.click(); + cookies = getCookies(); + assert.equal(Object.keys(cookies).length, 0, 'cookie не удалена из браузера'); + assert.equal(listTable.children.length, 0, 'cookie не удалена из таблицы'); + }); + + describe('Фильтрация', () => { + it('выводить список cookie, имя или значение которых соответствует фильтру', () => { + addNameInput.value = 'test-cookie-name-1'; + addValueInput.value = 'test-cookie-value-1'; + addButton.click(); + + addNameInput.value = 'test-cookie-name-2'; + addValueInput.value = 'test-cookie-value-2'; + addButton.click(); + + filterNameInput.value = 'test-cookie'; + filterNameInput.dispatchEvent(new KeyboardEvent('keyup')); + assert.equal(listTable.children.length, 2); + + filterNameInput.value = 'name-1'; + filterNameInput.dispatchEvent(new KeyboardEvent('keyup')); + assert.equal(listTable.children.length, 1); + + filterNameInput.value = 'name-2'; + filterNameInput.dispatchEvent(new KeyboardEvent('keyup')); + assert.equal(listTable.children.length, 1); + }); + + it('добавлять cookie в таблицу, только если значение cookie соответствует фильтру', () => { + let cookies; + + addNameInput.value = 'test-cookie-name-1'; + addValueInput.value = 'test-cookie-value-1'; + addButton.click(); + + addNameInput.value = 'test-cookie-name-2'; + addValueInput.value = 'test-cookie-value-2'; + addButton.click(); + + filterNameInput.value = 'value-2'; + filterNameInput.dispatchEvent(new KeyboardEvent('keyup')); + assert.equal(listTable.children.length, 1); + + addNameInput.value = 'test-cookie-name-3'; + addValueInput.value = 'test-cookie-more-value-2'; + addButton.click(); + + cookies = getCookies(); + assert(cookies.hasOwnProperty(addNameInput.value), 'должна быть добавлена в браузер'); + assert.equal(cookies[addNameInput.value], addValueInput.value, 'должна быть добавлена в браузер'); + assert.equal(listTable.children.length, 2, 'должна быть в таблице т.к. соответствует фильтру'); + }); + + it('не добавлять cookie в таблицу, если значение cookie не соответствует фильтру', () => { + let cookies; + + addNameInput.value = 'test-cookie-name-1'; + addValueInput.value = 'test-cookie-value-1'; + addButton.click(); + + addNameInput.value = 'test-cookie-name-2'; + addValueInput.value = 'test-cookie-value-2'; + addButton.click(); + + filterNameInput.value = 'value-2'; + filterNameInput.dispatchEvent(new KeyboardEvent('keyup')); + assert.equal(listTable.children.length, 1); + + addNameInput.value = 'test-cookie-name-3'; + addValueInput.value = 'test-cookie-value-3'; + addButton.click(); + + cookies = getCookies(); + assert(cookies.hasOwnProperty(addNameInput.value), 'должна быть добавлена в браузер'); + assert.equal(cookies[addNameInput.value], addValueInput.value, 'должна быть добавлена в браузер'); + assert.equal(listTable.children.length, 1, 'не должна быть в таблице т.к. не соответствует фильтру'); + }); + + it('удалить cookie из табилицы, если ее значение перестало соответствовать фильтр', () => { + let cookies; + + addNameInput.value = 'test-cookie-name-1'; + addValueInput.value = 'test-cookie-value-1'; + addButton.click(); + + addNameInput.value = 'test-cookie-name-2'; + addValueInput.value = 'test-cookie-value-2'; + addButton.click(); + + addNameInput.value = 'test-cookie-name-3'; + addValueInput.value = 'test-cookie-value-2'; + addButton.click(); + + filterNameInput.value = 'value-2'; + filterNameInput.dispatchEvent(new KeyboardEvent('keyup')); + assert.equal(listTable.children.length, 2); + + addNameInput.value = 'test-cookie-name-3'; + addValueInput.value = 'test-cookie-value-3'; + addButton.click(); + + cookies = getCookies(); + assert(cookies.hasOwnProperty(addNameInput.value), 'должна оставться в браузере'); + assert.equal(cookies[addNameInput.value], addValueInput.value, 'значение в браузере должно измениться'); + assert.equal(listTable.children.length, 1, 'уже не соответствует фильтру и не должна быть в таблице'); + }); + + it('выводить все cookie, если фильтр не задан', () => { + addNameInput.value = 'test-cookie-name-1'; + addValueInput.value = 'test-cookie-value-1'; + addButton.click(); + + addNameInput.value = 'test-cookie-name-2'; + addValueInput.value = 'test-cookie-value-2'; + addButton.click(); + + filterNameInput.value = ''; + filterNameInput.dispatchEvent(new KeyboardEvent('keyup')); + assert.equal(listTable.children.length, 2); + }); + }); + }); +}); diff --git a/test/index.js b/test/index.js deleted file mode 100644 index fd37df3..0000000 --- a/test/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import assert from 'assert'; - -describe('Test', () => { - it('should work', () => { - assert.isTrue(true); - }); -});