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)