1
0
Fork 0
mirror of https://github.com/shouptech/humulus.git synced 2026-02-03 17:09:44 +00:00

Add backend for updating recipes

This commit is contained in:
Emma 2019-06-23 11:10:09 -06:00
parent 9e510c0cfb
commit d37f51b168
4 changed files with 71 additions and 12 deletions

View file

@ -90,13 +90,12 @@ def put_doc(doc):
# Use a UUID for name
doc['_id'] = str(uuid.uuid4())
return db.create_document(doc)
return db.create_document(doc, throw_on_exists=True)
def get_doc(id):
"""Gets a doc from CouchDB and returns it."""
db = get_db()
return db[id]
return get_db()[id]
def get_doc_or_404(id):

View file

@ -16,7 +16,7 @@
from decimal import Decimal
from flask import Blueprint, flash, redirect, render_template, url_for
from flask import Blueprint, flash, redirect, render_template, request, url_for
from flask_wtf import FlaskForm
from wtforms import (Form, StringField, DecimalField, TextAreaField, FieldList,
FormField, SelectField)
@ -92,7 +92,7 @@ class YeastForm(Form):
CSRF is disabled for this subform (using `Form as parent class) because it
is never used by itself.
"""
name = StringField('Name', validators=[DataRequired()])
name = StringField('Name', validators=[Optional()])
type = SelectField('Type', default='',
choices=[(c, c) for c in ['', 'Liquid', 'Dry']],
validators=[Optional()])
@ -103,9 +103,9 @@ class YeastForm(Form):
'Medium', 'High']],
validators=[Optional()])
low_attenuation = DecimalField('Low Attenuation',
validators=[DataRequired()])
validators=[Optional()])
high_attenuation = DecimalField('High Attenuation',
validators=[DataRequired()])
validators=[Optional()])
min_temperature = DecimalField('Min Temp (°F)',
validators=[Optional()])
max_temperature = DecimalField('Max Temp (°F)',
@ -203,3 +203,30 @@ def delete(id):
recipe = get_doc_or_404(id)
recipe.delete()
return redirect(url_for('home.index'))
@bp.route('/update/<id>', methods=('GET', 'POST'))
def update(id):
# Get the recipe from the database and validate it is the same revision
recipe = get_doc_or_404(id)
form = RecipeForm()
if form.validate_on_submit():
if recipe['_rev'] != request.args.get('rev', None):
flash(
(
'Update conflict for recipe: {}. '
'Your changes have been lost.'.format(recipe['name'])
),
'error'
)
return redirect(url_for('recipes.info', id=id))
# Copy values from submitted form to the existing recipe and save
for key, value in form.doc.items():
recipe[key] = value
recipe.save()
flash('Updated recipe: {}'.format(form.name.data), 'success')
return redirect(url_for('recipes.info', id=id))
return render_template('recipes/update.html', form=form)

View file

@ -14,7 +14,7 @@
from decimal import Decimal
from humulus.couch import get_db
from humulus.couch import get_db, get_doc
from humulus.recipes import FermentableForm, HopForm, RecipeForm, YeastForm
@ -30,15 +30,12 @@ def test_create(client, app):
'name': 'Test',
'notes': 'Test',
'volume': '5.5',
'yeast-name': 'Test',
'yeast-low_attenuation': '60',
'yeast-high_attenuation': '75',
}
response = client.post('/recipes/create', data=data)
assert response.status_code == 302
with app.app_context():
doc = get_db()['test']
doc = get_doc('test')
assert doc['name'] == 'Test'
assert doc['notes'] == 'Test'
@ -46,6 +43,42 @@ def test_create(client, app):
assert doc['efficiency'] == '65'
def test_update(client, app):
"""Test success in updating a recipe document."""
# Test GET
id = 'awesome-lager'
response = client.get('/recipes/update/{}'.format(id))
# Get the doc, test a change, then post the update
with app.app_context():
data = get_doc(id)
# Remove values that should not be posted with the data
rev = data.pop('_rev') # Save the revision, will be used later
data.pop('_id')
# Make a change to the data
data['name'] = '{} TEST'.format(data['name'])
# Test valid response
response = client.post('/recipes/update/{}'.format(id),
query_string={'rev': rev}, data=data)
assert response.status_code == 302
with client.session_transaction() as session:
flash_message = dict(session['_flashes']).get('error')
assert flash_message is None
# Test response without valid/conflicted rev
response = client.post('/recipes/update/{}'.format(id),
query_string={'rev': ''}, data=data)
assert response.status_code == 302
with client.session_transaction() as session:
flash_message = dict(session['_flashes']).get('error')
assert 'Update conflict' in flash_message
with app.app_context():
updated = get_doc(id)
assert updated['name'] == data['name']
def test_info(client):
"""Test success in retrieving a recipe document."""
# Validate 404