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:
parent
9e510c0cfb
commit
d37f51b168
4 changed files with 71 additions and 12 deletions
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
0
src/humulus/templates/recipes/update.html
Normal file
0
src/humulus/templates/recipes/update.html
Normal 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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue