diff --git a/README.md b/README.md
index d55828d..2fa509e 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,73 @@
-./scripts/bootstrap.sh
+# Todo List App
+
+The Todo List App is an application for creating and sharing todolists.
+
+This repo contains:
+
+* Resources for creating users, todo lists, todos, and todo list permissions.
+* User tests for the above resources.
+
+
+## Environment Setup
+
+Clone the repository:
+
+`git clone https://github.com/cfierro/todo.git`
+
+Grab your fork:
+
+'git remote add [yourname] https://github.com/[yourname]/todo.git'
+
+Install dependencies using the bootstrap script:
+
+`./scripts/bootstrap.sh`
+
+
+## Directory Structure
+
+* app/authentication - resources for user authentication
+ * log in
+ * log out
+ * get logged in user info
+* app/lib - shared libraries across multiple resources
+ * /authenticaion - decorator for requiring a user to be logged in
+ * /models - includes a base table mixin for all data tables
+ * /response_uit - methods for building status responses
+ * /status - classes for returning raised exceptions
+* app/permissions - model and resources for list permissions
+* app/todo_lists - model and resources for todo lists
+* app/todos - model and resources for todos
+* app/users - model and resources for users
+* app/__init__.py - initialize python packages. Includes:
+ * Import Flask libraries
+ * Error handler
+ * database creation
+ * Model imports
+ * Resources urls for APIs
+* env - virtual environment
+* scripts - bootstrap script fo installing dependencies
+* unittest/resources - unittests for user, todo, todo_list, and auth resources
+* .gitignore - files to ignore upon git commit
+* config.py -
+* README.md - this file!
+* requirements.txt - required libraries
+* run.py - runs the application.
+* shell.py -
+
+
+## Development
+
+Run the following from the top level directory:
+
+Activate your virutual environment.
+
+`source env/bin/activate`
+
+To run the app:
+
+`python run.py`
+
+To run unit tests:
+
+`py.test unittest`
-source env/bin/activate
diff --git a/app.db b/app.db
index ed6ecae..b57baa7 100644
Binary files a/app.db and b/app.db differ
diff --git a/app/static/css/main.css b/app/static/css/main.css
index e69de29..d882ac1 100644
--- a/app/static/css/main.css
+++ b/app/static/css/main.css
@@ -0,0 +1,34 @@
+body {
+ font-family: 'Josefin Sans', sans-serif;
+ font-size: 18px;
+ background: #BAA5D6; }
+
+.todo-app h1 {
+ text-align: center; }
+
+.todo-lists-container {
+ width: 50%;
+ margin: 0 auto; }
+ .todo-lists-container ul {
+ list-style: none;
+ margin-left: 0;
+ padding-left: 0; }
+
+.listName {
+ outline: none;
+ border: none;
+ background: transparent;
+ font-family: 'Josefin Sans', sans-serif;
+ font-size: 1.5em;
+ text-align: center;
+ width: 80%; }
+ .listName:focus + .deleteList {
+ display: inline-block; }
+
+.todo {
+ outline: none;
+ padding: 3px;
+ width: 80%; }
+
+.addList {
+ margin: 0 auto; }
diff --git a/app/templates/index.html b/app/templates/index.html
index 96b3033..1ebe36b 100644
--- a/app/templates/index.html
+++ b/app/templates/index.html
@@ -2,6 +2,7 @@
+
diff --git a/app/todo_lists/resources.py b/app/todo_lists/resources.py
index 4a388f3..bb327a0 100644
--- a/app/todo_lists/resources.py
+++ b/app/todo_lists/resources.py
@@ -1,3 +1,5 @@
+import json
+
from flask import request, session
from flask_restful import Resource
from sqlalchemy import and_
@@ -30,10 +32,12 @@ def get(self):
def post(self):
"""Method creates a todoList and returns it in an Ok response.
"""
- if not(request.form.get('name')):
+ data = json.loads(request.data)
+
+ if not(data.get('name')):
raise status.BadRequest()
- todoList = TodoList(request.form.get('name'), session.get('userId'))
+ todoList = TodoList(data.get('name'), session.get('userId'))
db.session.add(todoList)
db.session.commit()
@@ -56,6 +60,7 @@ def put(self, todoListId):
"""
userId = session.get('userId')
todoList = TodoList.query.get(todoListId)
+ data = json.loads(request.data)
if todoList is None:
raise status.NotFound()
@@ -67,7 +72,7 @@ def put(self, todoListId):
if permission is None:
raise status.Unauthorized()
- todoList.name = request.form.get('name') or todoList.name
+ todoList.name = data.get('name') or todoList.name
db.session.commit()
return response_util.buildOkResponse(todoList.toDict())
diff --git a/app/todos/resources.py b/app/todos/resources.py
index 71f8964..0c35266 100644
--- a/app/todos/resources.py
+++ b/app/todos/resources.py
@@ -1,3 +1,5 @@
+import json
+
from flask import request, session
from flask_restful import Resource
from sqlalchemy import and_
@@ -44,10 +46,11 @@ def get(self):
def post(self):
"""Method adds a new todo and returns the todo in an OK response..
"""
+ data = json.loads(request.data)
userId = session.get('userId')
- todoListId = request.form.get('todoListId')
+ todoListId = data.get('todoListId')
- if not(request.form.get('subject') and todoListId):
+ if not(data.get('subject') and todoListId):
raise status.BadRequest()
permission = TodoListPermission.query.filter(
@@ -57,14 +60,14 @@ def post(self):
if permission is None:
raise status.Forbidden()
- todo = Todo(request.form.get('subject'),
+ todo = Todo(data.get('subject'),
todoListId,
userId,
- request.form.get('dueDate'),
- request.form.get('description'),
- request.form.get('priority'),
- request.form.get('completed'),
- request.form.get('assigneeId'))
+ data.get('dueDate'),
+ data.get('description'),
+ data.get('priority'),
+ data.get('completed'),
+ data.get('assigneeId'))
db.session.add(todo)
db.session.commit()
@@ -81,6 +84,7 @@ def put(self, todoId):
Args:
todoId - Interger, primary key identifying the todo.
"""
+ data = json.loads(request.data)
userId = session.get('userId')
todo = Todo.query.get(todoId)
@@ -94,12 +98,15 @@ def put(self, todoId):
if permission is None:
raise status.Forbidden()
- todo.subject = request.form.get('subject') or todo.subject
- todo.dueDate = request.form.get('dueDate') or todo.dueDate
- todo.description = request.form.get('description') or todo.description
- todo.priority = request.form.get('priority') or todo.priority
- todo.completed = request.form.get('completed') or todo.completed
- todo.assigneeId = request.form.get('assigneeId') or todo.assigneeId
+ todo.subject = data.get('subject') or todo.subject
+ todo.dueDate = data.get('dueDate') or todo.dueDate
+ todo.description = data.get('description') or todo.description
+ todo.priority = data.get('priority') or todo.priority
+ todo.assigneeId = data.get('assigneeId') or todo.assigneeId
+
+ todo.completed = data.get('completed') \
+ if data.get('completed') != todo.completed \
+ else todo.completed
db.session.commit()
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 0000000..75c715c
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,13 @@
+var gulp = require('gulp');
+var sass = require('gulp-sass');
+
+gulp.task('styles', function() {
+ gulp.src('sass/**/*.scss')
+ .pipe(sass().on('error', sass.logError))
+ .pipe(gulp.dest('./app/static/css'));
+});
+
+//Watch task
+gulp.task('default',function() {
+ gulp.watch('sass/**/*.scss',['styles']);
+});
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..e69de29
diff --git a/js/src/Collection/ItemCollection.js b/js/src/Collection/ItemCollection.js
deleted file mode 100644
index cd644da..0000000
--- a/js/src/Collection/ItemCollection.js
+++ /dev/null
@@ -1,9 +0,0 @@
-var Backbone = require('backbone');
-
-var ItemModel = require('../Model/ItemModel.js');
-
-var ItemCollection = Backbone.Collection.extend({
- model: ItemModel
-});
-
-module.exports = ItemCollection;
diff --git a/js/src/Collection/TodoCollection.js b/js/src/Collection/TodoCollection.js
new file mode 100644
index 0000000..070d425
--- /dev/null
+++ b/js/src/Collection/TodoCollection.js
@@ -0,0 +1,18 @@
+var Backbone = require('backbone');
+
+var TodoModel = require('../Model/TodoModel.js');
+
+var TodoCollection = Backbone.Collection.extend({
+ initialize: function(models, options){
+ this.id = options.id
+ },
+ model: TodoModel,
+ url: function(){
+ return '/todos?todoListId=' + this.id;
+ },
+ parse: function(response){
+ return response.result;
+ }
+})
+
+module.exports = TodoCollection;
diff --git a/js/src/Collection/TodoListCollection.js b/js/src/Collection/TodoListCollection.js
new file mode 100644
index 0000000..e8cfaf7
--- /dev/null
+++ b/js/src/Collection/TodoListCollection.js
@@ -0,0 +1,13 @@
+var Backbone = require('backbone');
+
+var TodoListModel = require('../Model/TodoListModel.js');
+
+var TodoListCollection = Backbone.Collection.extend({
+ model: TodoListModel,
+ url: '/todolists',
+ parse: function(response){
+ return response.result;
+ }
+})
+
+module.exports = TodoListCollection;
diff --git a/js/src/Model/ItemModel.js b/js/src/Model/ItemModel.js
deleted file mode 100644
index fc783c6..0000000
--- a/js/src/Model/ItemModel.js
+++ /dev/null
@@ -1,10 +0,0 @@
-var Backbone = require('backbone');
-
-var ItemModel = Backbone.Model.extend({
- defaults: {
- part1: 'hello',
- part2: 'world'
- }
-});
-
-module.exports = ItemModel;
diff --git a/js/src/Model/TodoListModel.js b/js/src/Model/TodoListModel.js
new file mode 100644
index 0000000..ced6448
--- /dev/null
+++ b/js/src/Model/TodoListModel.js
@@ -0,0 +1,18 @@
+var Backbone = require('backbone');
+// var TodoListCollection = require('../Collection/TodoListCollection.js')
+
+var TodoListModel = Backbone.Model.extend({
+ urlRoot: '/todolists',
+ defaults: {
+ name: 'List Name',
+ creator: 'User'
+ },
+ parse: function(response, options){
+ if (options.collection) {
+ return response;
+ }
+ return response.result;
+ }
+})
+
+module.exports = TodoListModel;
diff --git a/js/src/Model/TodoModel.js b/js/src/Model/TodoModel.js
new file mode 100644
index 0000000..f0f0af9
--- /dev/null
+++ b/js/src/Model/TodoModel.js
@@ -0,0 +1,21 @@
+var Backbone = require('backbone');
+
+var TodoModel = Backbone.Model.extend({
+ urlRoot: 'todos/',
+ defaults: {
+ subject: 'Subject',
+ dueDate: null,
+ description: '',
+ priority: null,
+ completed: false,
+ assignee: null,
+ },
+ parse: function(response, options){
+ if (options.collection) {
+ return response;
+ }
+ return response.result;
+ }
+})
+
+module.exports = TodoModel;
diff --git a/js/src/Model/UserModel.js b/js/src/Model/UserModel.js
new file mode 100644
index 0000000..7b9d5ea
--- /dev/null
+++ b/js/src/Model/UserModel.js
@@ -0,0 +1,11 @@
+var Backbone = require('backbone');
+
+var UserModel = Backbone.Model.extend({
+ url: '/me',
+ parse: function(response){
+ return response.result;
+ }
+
+})
+
+module.exports = UserModel;
diff --git a/js/src/View/AppView.js b/js/src/View/AppView.js
new file mode 100644
index 0000000..ffe829f
--- /dev/null
+++ b/js/src/View/AppView.js
@@ -0,0 +1,87 @@
+var Backbone = require('backbone');
+var $ = require('jquery');
+var _ = require('underscore');
+var handlebars = require('handlebars');
+
+var UserModel = require('../Model/UserModel.js');
+var appViewTemplate = require('../templates/container.hbs');
+var TodoListView = require('./TodoListView.js');
+var TodoListCollection = require('../Collection/TodoListCollection.js');
+var TodoListModel = require('../Model/TodoListModel.js');
+var todoAppTemplate = require('../templates/todoapp.hbs');
+
+var AppView = Backbone.View.extend({
+ el: 'body',
+ events: {
+ 'click .addlist': 'addNewList',
+ },
+
+ initialize: function(){
+
+ this.render();
+
+ this.user = new UserModel();
+ this.user.fetch({
+ success: _.bind(function(model){
+ console.log('Success: user loaded.');
+ this.renderUser();
+ }, this),
+ error: function(){
+ console.log('Error: user failed to load.');
+ }
+ })
+
+ this.todoLists = new TodoListCollection();
+ this.todoLists.fetch({
+ success: _.bind(function(model){
+ console.log('Success: todoLists loaded.');
+ this.renderTodoLists();
+ }, this),
+ error: function(){
+ console.log('Error: todolists failed to load.');
+ }
+ });
+ },
+
+ render: function(){
+ this.el.insertAdjacentHTML('afterbegin', todoAppTemplate({}));
+ },
+
+ renderUser: function(){
+ this.el.querySelector('.user-container').innerHTML = appViewTemplate({userName: this.user.get('name')});
+
+ },
+
+ renderTodoLists: function(){
+ this.todoLists.each(function(todoList, i){
+ var todoListView = new TodoListView({
+ model: todoList
+ })
+ this.el.querySelector('.todo-lists-container').appendChild(todoListView.el)
+ }, this)
+ },
+
+ addNewList: function(){
+ var newList = new TodoListModel({
+ name: "name",
+ })
+
+ newList.save(null, {
+ success: _.bind(function(model) {
+ console.log('Success: todoList created.');
+
+ this.todoLists.add(newList);
+ var todoListView = new TodoListView({
+ model: newList
+ })
+ this.el.querySelector('.todo-lists-container').appendChild(todoListView.el)
+ }, this),
+ error: function(){
+ console.log('Error: todolists not created.');
+ }
+ });
+ },
+
+})
+
+module.exports = AppView;
diff --git a/js/src/View/ItemView.js b/js/src/View/ItemView.js
deleted file mode 100644
index 1fb95ec..0000000
--- a/js/src/View/ItemView.js
+++ /dev/null
@@ -1,19 +0,0 @@
-var Backbone = require('backbone');
-var $ = require('jquery');
-var _ = require('underscore');
-
-var ItemView = Backbone.View.extend({
- tagName: 'li',
-
- initialize: function() {
- _.bindAll(this, 'render');
- },
-
- render: function() {
- $(this.el).html('' + this.model.get('part1') + ' ' +
- this.model.get('part2') + '');
- return this;
- }
-});
-
-module.exports = ItemView;
diff --git a/js/src/View/ListView.js b/js/src/View/ListView.js
deleted file mode 100644
index 2b998e8..0000000
--- a/js/src/View/ListView.js
+++ /dev/null
@@ -1,53 +0,0 @@
-var Backbone = require('backbone');
-var $ = require('jquery');
-var _ = require('underscore');
-
-var ItemCollection = require('../Collection/ItemCollection.js');
-var ItemModel = require('../Model/ItemModel.js');
-var ItemView = require('./ItemView.js');
-
-var ListView = Backbone.View.extend({
- el: $('body'),
-
- events: {
- 'click button#add': 'addItem',
- },
-
- initialize: function() {
- _.bindAll(this, 'render', 'addItem', 'appendItem');
-
- this.collection = new ItemCollection();
-
- this.collection.bind('add', this.appendItem);
-
- this.counter = 0;
- this.render();
- },
-
- render: function() {
- var self = this;
- $(this.el).append("");
- $(this.el).append("");
- _(this.collection.models).each(function(item) {
- self.appendItem(item);
- }, this);
- },
-
- addItem: function() {
- this.counter++;
- var item = new ItemModel();
- item.set({
- part2: item.get('part2') + this.counter
- });
- this.collection.add(item);
- },
-
- appendItem: function(item) {
- var itemView = new ItemView({
- model: item
- });
- $('ul', this.el).append(itemView.render().el);
- }
-});
-
-module.exports = ListView;
diff --git a/js/src/View/TodoListView.js b/js/src/View/TodoListView.js
new file mode 100644
index 0000000..cce24f0
--- /dev/null
+++ b/js/src/View/TodoListView.js
@@ -0,0 +1,116 @@
+var Backbone = require('backbone');
+var $ = require('jquery');
+var _ = require('underscore');
+var handlebars = require('handlebars');
+
+var TodoListModel = require('../Model/TodoListModel.js');
+var TodoModel = require('../Model/TodoModel.js');
+var TodoListCollection = require('../Collection/TodoListCollection.js');
+var TodoCollection = require('../Collection/TodoCollection.js');
+var TodoView = require('./TodoView.js')
+
+
+var todoListViewTemplate = require('../templates/todolist.hbs');
+
+
+var TodoListView = Backbone.View.extend({
+ //why does $ syntax not work here?
+
+ tagName: 'div',
+ className: 'todo-list-container',
+
+ events: {
+ 'click .deleteList': 'deleteList',
+ 'keypress .todo': 'addTodoKeyPress',
+ 'click .addTodo': 'addTodoClick',
+ 'keypress .listName': 'updateList',
+ },
+
+ initialize: function(){
+ // create todoList model
+ this.renderTodoList();
+
+ // create todo collection
+ this.todos = new TodoCollection([], {id: this.model.id});
+ this.todos.fetch({
+ success: _.bind(function(model){
+ console.log('Success: Todos loaded.');
+ this.renderTodos();
+
+ }, this),
+ error: function(){
+ console.log('Error: Todos failed to load.');
+ }
+ })
+
+ },
+
+ renderTodoList: function(){
+ var todoList = this.model.toJSON();
+ this.el.innerHTML = todoListViewTemplate({listName: todoList.name});
+
+ },
+
+ renderTodos: function(){
+ this.todos.each(function(todo){
+ var todoView = new TodoView({
+ model: todo
+ })
+ this.el.querySelector('ul').appendChild(todoView.el)
+ }, this)
+ },
+
+ deleteList: function(){
+ this.model.destroy();
+ this.el.parentNode.removeChild(this.el);
+ },
+
+ _addTodo: function(){
+ var todoListId = this.model.id;
+
+ var newTodo = new TodoModel({
+ subject: 'subject',
+ todoListId: todoListId
+ })
+
+ newTodo.save(null, {
+ success: _.bind(function(model) {
+ console.log('Success: todo created.');
+
+ this.todos.add(newTodo);
+ var todoView = new TodoView({
+ model: newTodo
+ })
+ this.el.querySelector('ul').appendChild(todoView.el);
+ this.el.querySelector('ul li:last-child input.todo').focus();
+ }, this),
+ error: function(){
+ console.log('Error: todo not created.');
+ }
+ })
+ },
+
+ addTodoKeyPress: function(e){
+ var code = e.keyCode;
+ var lastItem = this.el.querySelector('ul li:last-child input.todo');
+ if (code === 13 && e.currentTarget === lastItem) {
+ this._addTodo();
+ }
+ },
+
+ addTodoClick: function(){
+ this._addTodo();
+ },
+
+ updateList: function(e){
+ var code = e.keyCode;
+ var newListName = e.currentTarget.value;
+
+ if (code === 13) {
+ this.model.save({'name': newListName})
+ e.currentTarget.blur();
+ }
+ },
+})
+
+module.exports = TodoListView;
diff --git a/js/src/View/TodoView.js b/js/src/View/TodoView.js
new file mode 100644
index 0000000..4177416
--- /dev/null
+++ b/js/src/View/TodoView.js
@@ -0,0 +1,53 @@
+var Backbone = require('backbone');
+var $ = require('jquery');
+var _ = require('underscore');
+var handlebars = require('handlebars');
+
+var TodoCollection = require('../Collection/TodoCollection.js');
+var TodoModel = require('../Model/TodoModel.js');
+
+var todoViewTemplate = require('../templates/todo.hbs');
+
+
+var TodoView = Backbone.View.extend({
+ tagName: 'li',
+ className: 'todoContainer',
+ events: {
+ 'keypress .todo': 'updateTodo',
+ 'click .deleteTodo': 'deleteTodo',
+ 'click .todoCheckBox': 'markComplete',
+ },
+
+ initialize: function(){
+ // this.todo = new TodoModel();
+ this.render();
+ },
+
+ render: function(){
+ var todo = this.model.toJSON();
+ this.el.innerHTML = todoViewTemplate({subject: todo.subject});
+ },
+
+ updateTodo: function(e){
+ var code = e.keyCode
+ var newSubject = e.currentTarget.value;
+
+ if (code === 13) {
+ this.model.save({"subject": newSubject});
+ e.currentTarget.blur();
+ }
+ },
+
+ deleteTodo: function(){
+
+ this.model.destroy();
+ this.el.parentNode.removeChild(this.el);
+ },
+
+ markComplete: function(){
+ this.model.save({"completed": !this.model.get('completed')});
+
+ },
+})
+
+module.exports = TodoView;
diff --git a/js/src/main.js b/js/src/main.js
index 1bee37f..cfd6432 100644
--- a/js/src/main.js
+++ b/js/src/main.js
@@ -1,3 +1,4 @@
-var ListView = require('./View/ListView.js');
+var AppView = require('./View/AppView.js');
+
+var appView = new AppView();
-var listView = new ListView();
diff --git a/js/src/templates/container.hbs b/js/src/templates/container.hbs
new file mode 100644
index 0000000..6c15c44
--- /dev/null
+++ b/js/src/templates/container.hbs
@@ -0,0 +1,2 @@
+{{userName}}'s Tasks
+
diff --git a/js/src/templates/todo.hbs b/js/src/templates/todo.hbs
new file mode 100644
index 0000000..97f1680
--- /dev/null
+++ b/js/src/templates/todo.hbs
@@ -0,0 +1,3 @@
+
+
+
diff --git a/js/src/templates/todoapp.hbs b/js/src/templates/todoapp.hbs
new file mode 100644
index 0000000..9322bb7
--- /dev/null
+++ b/js/src/templates/todoapp.hbs
@@ -0,0 +1,7 @@
+
diff --git a/js/src/templates/todolist.hbs b/js/src/templates/todolist.hbs
new file mode 100644
index 0000000..3476d4f
--- /dev/null
+++ b/js/src/templates/todolist.hbs
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/notes.txt b/notes.txt
new file mode 100644
index 0000000..bd5deac
--- /dev/null
+++ b/notes.txt
@@ -0,0 +1,16 @@
+When all todos are deleted render a button to add new todo
+
+Make it pretty.
+
+
+Redis for ordering lists?
+
+Create a login screen
+
+
+
+
+
+
+
+
diff --git a/npm-debug.log b/npm-debug.log
new file mode 100644
index 0000000..e69de29
diff --git a/package.json b/package.json
index a346d72..ccc1bea 100644
--- a/package.json
+++ b/package.json
@@ -7,10 +7,10 @@
"frontend"
],
"scripts": {
- "build": "browserify ./js/src/main.js -o ./app/static/js/main.js",
- "watch": "watchify ./js/src/main.js -o ./app/static/js/main.js -dv",
+ "build": "browserify -t hbsfy ./js/src/main.js -o ./app/static/js/main.js",
+ "watch": "watchify -t hbsfy ./js/src/main.js -o ./app/static/js/main.js -dv",
"server": "source ./env/bin/activate && python run.py",
- "start": "npm run watch & npm run server"
+ "start": "npm run watch & npm run server & gulp"
},
"license": "MIT",
"repository": {
@@ -19,11 +19,15 @@
},
"devDependencies": {
"browserify": "^11.2.0",
- "watchify": "^3.4.0"
+ "watchify": "^3.4.0",
+ "hbsfy": "^2.4.1",
+ "gulp": "^3.9.0",
+ "gulp-sass": "^2.1.1"
},
"dependencies": {
"backbone": "^1.1.3",
"jquery": "^2.1.4",
- "underscore": "^1.8.3"
+ "underscore": "^1.8.3",
+ "handlebars": "^4.0.2"
}
}
diff --git a/sass/main.scss b/sass/main.scss
new file mode 100644
index 0000000..d8c482e
--- /dev/null
+++ b/sass/main.scss
@@ -0,0 +1,59 @@
+
+body {
+ font-family: 'Josefin Sans', sans-serif;
+ font-size: 18px;
+ background: #BAA5D6;
+}
+.todo-app {
+ h1 {
+ text-align: center;
+ }
+}
+.todo-lists-container {
+ width: 50%;
+ margin: 0 auto;
+
+ ul {
+ list-style: none;
+ margin-left: 0;
+ padding-left: 0;
+ }
+}
+// .deleteList {
+// display: none;
+// }
+.listName {
+ outline: none;
+ border: none;
+ background: transparent;
+
+ font-family: 'Josefin Sans', sans-serif;
+ font-size: 1.5em;
+ text-align: center;
+ width: 80%;
+
+ &:focus + .deleteList {
+ display: inline-block;
+ }
+}
+// .deleteTodo {
+// display: none;
+// }
+.todo {
+ outline: none;
+ padding: 3px;
+ width: 80%;
+
+}
+// li:focus {
+// .deleteTodo {
+// display: inline-block;
+// }
+// }
+.addList {
+ margin: 0 auto;
+}
+
+
+
+
diff --git a/unittest/resources/test_todo.py b/unittest/resources/test_todo.py
index e9d9f53..5158fd0 100644
--- a/unittest/resources/test_todo.py
+++ b/unittest/resources/test_todo.py
@@ -147,7 +147,8 @@ def test_post_success(self):
'assigneeId': 1
}
- resp = self.client.post('/todos/?todolist=1', data=todo)
+ resp = self.client.post('/todos/?todolist=1', data=json.dumps(todo),
+ content_type='application/json')
assert resp.status_code == 200
assert json.loads(resp.data) == {
@@ -177,7 +178,8 @@ def test_post_badRequest(self):
self.client.get('/login/%s' % self.user.id)
todo = {}
- resp = self.client.post('/todos/', data=todo)
+ resp = self.client.post('/todos/', data=json.dumps(todo),
+ content_type='application/json')
assert resp.status_code == 400
assert json.loads(resp.data) == {
@@ -208,7 +210,8 @@ def test_put_success(self):
'completed': 1
}
- resp = self.client.put('/todos/%s' % todo.id, data=newTodoData)
+ resp = self.client.put('/todos/%s' % todo.id, data=json.dumps(newTodoData),
+ content_type='application/json')
assert resp.status_code == 200
assert json.loads(resp.data) == {
@@ -236,8 +239,7 @@ def test_put_notFound(self):
"""Verify notFound is raised if todo with the given id does not exist.
"""
self.client.get('/login/%s' % self.user.id)
-
- resp = self.client.put('/todos/1000')
+ resp = self.client.put('/todos/1000', data='{}', content_type='application/json')
assert resp.status_code == 404
assert json.loads(resp.data) == {
diff --git a/unittest/resources/test_todo_list.py b/unittest/resources/test_todo_list.py
index a1ea116..95ba669 100644
--- a/unittest/resources/test_todo_list.py
+++ b/unittest/resources/test_todo_list.py
@@ -146,7 +146,7 @@ def test_post_success(self):
'name': 'Test List'
}
- resp = self.client.post('/todolists/', data=todoList)
+ resp = self.client.post('/todolists/', data=json.dumps(todoList), content_type='application/json')
assert resp.status_code == 200
assert json.loads(resp.data) == {
@@ -170,7 +170,7 @@ def test_post_badRequest(self):
todoList = {}
- resp = self.client.post('/todolists/', data=todoList)
+ resp = self.client.post('/todolists/', data=json.dumps(todoList), content_type='application/json')
assert resp.status_code == 400
assert json.loads(resp.data) == {
@@ -204,7 +204,9 @@ def test_put_success(self):
'name': 'Updated List'
}
- resp = self.client.put('/todolists/%s' % todoList.id, data=newListData)
+ resp = self.client.put('/todolists/%s' % todoList.id,
+ data=json.dumps(newListData),
+ content_type='application/json')
assert resp.status_code == 200
assert json.loads(resp.data) == {
@@ -227,8 +229,8 @@ def test_put_notFound(self):
"""
self.client.get('/login/%s' % self.user.id)
- resp = self.client.put('/todolists/1000')
-
+ resp = self.client.put('/todolists/1000', data='{}',
+ content_type='application/json')
assert resp.status_code == 404
assert json.loads(resp.data) == {
'info': {},
@@ -317,7 +319,7 @@ def test_delete_notFound(self):
'result': {}
}
- def test_put_unauthorized(self):
+ def test_delete_unauthorized(self):
"""Verify Unauthorized is raise when user is not logged in.
"""
todoList = TodoList('Test List', 1)