Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions examples/bootstrap4/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,10 +271,32 @@ def edit_message(message_id):
def delete_message(message_id):
message = Message.query.get(message_id)
if message:
# Get current page from referrer or request args
current_page = request.args.get('page', 1, type=int)
if request.referrer and 'page=' in request.referrer:
# Extract page number from referrer URL
import re
page_match = re.search(r'[?&]page=(\d+)', request.referrer)
if page_match:
current_page = int(page_match.group(1))

# Delete the message
db.session.delete(message)
db.session.commit()
return f'Message {message_id} has been deleted. Return to <a href="/table">table</a>.'
return f'Message {message_id} did not exist and could therefore not be deleted. Return to <a href="/table">table</a>.'

# Calculate total remaining messages and pages
total_messages = Message.query.count()
per_page = 10 # Same as used in test_table route
total_pages = max(1, (total_messages + per_page - 1) // per_page) # At least page 1

# Determine which page to redirect to
redirect_page = min(current_page, total_pages)

flash(f'Message {message_id} has been deleted.', 'success')
return redirect(url_for('test_table', page=redirect_page))
else:
flash(f'Message {message_id} did not exist and could therefore not be deleted.', 'warning')
return redirect(url_for('test_table'))


@app.route('/table/<int:message_id>/like')
Expand Down
26 changes: 24 additions & 2 deletions examples/bootstrap5/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,10 +295,32 @@ def edit_message(message_id):
def delete_message(message_id):
message = Message.query.get(message_id)
if message:
# Get current page from referrer or request args
current_page = request.args.get('page', 1, type=int)
if request.referrer and 'page=' in request.referrer:
# Extract page number from referrer URL
import re
page_match = re.search(r'[?&]page=(\d+)', request.referrer)
if page_match:
current_page = int(page_match.group(1))

# Delete the message
db.session.delete(message)
db.session.commit()
return f'Message {message_id} has been deleted. Return to <a href="/table">table</a>.'
return f'Message {message_id} did not exist and could therefore not be deleted. Return to <a href="/table">table</a>.'

# Calculate total remaining messages and pages
total_messages = Message.query.count()
per_page = 10 # Same as used in test_table route
total_pages = max(1, (total_messages + per_page - 1) // per_page) # At least page 1

# Determine which page to redirect to
redirect_page = min(current_page, total_pages)

flash(f'Message {message_id} has been deleted.', 'success')
return redirect(url_for('test_table', page=redirect_page))
else:
flash(f'Message {message_id} did not exist and could therefore not be deleted.', 'warning')
return redirect(url_for('test_table'))


@app.route('/table/<int:message_id>/like')
Expand Down
107 changes: 106 additions & 1 deletion tests/test_bootstrap4/test_render_pagination.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from flask import render_template_string, request
from flask import render_template_string, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy


Expand Down Expand Up @@ -36,3 +36,108 @@ def test():
assert '1</a>' in data
assert '<a class="page-link" href="#">2 <span class="sr-only">(current)</span></a>' in data
assert '10</a>' in data


def test_pagination_after_delete(app, client): # noqa: C901
"""Test that pagination works correctly after deleting items."""
db = SQLAlchemy(app)

class Message(db.Model):
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String(100))

@app.route('/table')
def test_table():
page = request.args.get('page', 1, type=int)
pagination = Message.query.paginate(page=page, per_page=10)
messages = pagination.items
return render_template_string('''
Page {{ pagination.page }} of {{ pagination.pages }}
Total: {{ pagination.total }}
Messages: {{ messages|length }}
''', pagination=pagination, messages=messages)

@app.route('/table/<int:message_id>/delete', methods=['POST'])
def delete_message(message_id):
message = Message.query.get(message_id)
if message:
# Get current page from request args or referrer
current_page = request.args.get('page', 1, type=int)
if request.referrer and 'page=' in request.referrer:
import re
page_match = re.search(r'[?&]page=(\d+)', request.referrer)
if page_match:
current_page = int(page_match.group(1))

# Delete the message
db.session.delete(message)
db.session.commit()

# Calculate total remaining messages and pages
total_messages = Message.query.count()
per_page = 10
total_pages = (total_messages + per_page - 1) // per_page if total_messages > 0 else 1

# Determine which page to redirect to
redirect_page = current_page
if total_pages == 0 or total_messages == 0:
redirect_page = 1
elif current_page > total_pages:
redirect_page = total_pages

flash(f'Message {message_id} has been deleted.', 'success')
return redirect(url_for('test_table', page=redirect_page))
else:
flash(f'Message {message_id} did not exist.', 'warning')
return redirect(url_for('test_table'))

with app.app_context():
# Test Case 1: Delete from middle page - should stay on same page
db.drop_all()
db.create_all()
for i in range(25): # Create 25 messages (3 pages of 10 each, 5 on last page)
msg = Message(text=f'Message {i+1}')
db.session.add(msg)
db.session.commit()

# Go to page 2 and delete a message
response = client.get('/table?page=2')
assert 'Page 2 of 3' in response.get_data(as_text=True)

# Delete message ID 15 (should be on page 2)
response = client.post('/table/15/delete?page=2', follow_redirects=True)
data = response.get_data(as_text=True)
assert 'Page 2 of 3' in data # Should still be on page 2
assert 'Total: 24' in data # One less message

# Test Case 2: Delete all items from last page - should redirect to previous page
db.drop_all()
db.create_all()
for i in range(21): # Create 21 messages (3 pages: 10, 10, 1)
msg = Message(text=f'Message {i+1}')
db.session.add(msg)
db.session.commit()

# Go to page 3 (last page with 1 item)
response = client.get('/table?page=3')
data = response.get_data(as_text=True)
assert 'Page 3 of 3' in data
assert 'Total: 21' in data

# Delete the only message on page 3
response = client.post('/table/21/delete?page=3', follow_redirects=True)
data = response.get_data(as_text=True)
assert 'Page 2 of 2' in data # Should redirect to page 2
assert 'Total: 20' in data # One less message

# Test Case 3: Delete all messages - should go to page 1
db.drop_all()
db.create_all()
msg = Message(text='Last message')
db.session.add(msg)
db.session.commit()

response = client.post('/table/1/delete', follow_redirects=True)
data = response.get_data(as_text=True)
assert 'Page 1 of' in data # Should be on page 1 (could be "Page 1 of 0" or "Page 1 of 1")
assert 'Total: 0' in data # No messages left
107 changes: 106 additions & 1 deletion tests/test_bootstrap5/test_pagination.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from flask import render_template_string, request
from flask import render_template_string, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy


Expand Down Expand Up @@ -30,3 +30,108 @@ def test():
assert '<a class="page-link" href="#">1 <span class="sr-only">(current)</span></a>' not in data
assert '<li class="page-item active" aria-current="page">' in data
assert '<a class="page-link" href="#">1</a>' in data


def test_pagination_after_delete(app, client): # noqa: C901
"""Test that pagination works correctly after deleting items."""
db = SQLAlchemy(app)

class Message(db.Model):
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String(100))

@app.route('/table')
def test_table():
page = request.args.get('page', 1, type=int)
pagination = Message.query.paginate(page=page, per_page=10)
messages = pagination.items
return render_template_string('''
Page {{ pagination.page }} of {{ pagination.pages }}
Total: {{ pagination.total }}
Messages: {{ messages|length }}
''', pagination=pagination, messages=messages)

@app.route('/table/<int:message_id>/delete', methods=['POST'])
def delete_message(message_id):
message = Message.query.get(message_id)
if message:
# Get current page from request args or referrer
current_page = request.args.get('page', 1, type=int)
if request.referrer and 'page=' in request.referrer:
import re
page_match = re.search(r'[?&]page=(\d+)', request.referrer)
if page_match:
current_page = int(page_match.group(1))

# Delete the message
db.session.delete(message)
db.session.commit()

# Calculate total remaining messages and pages
total_messages = Message.query.count()
per_page = 10
total_pages = (total_messages + per_page - 1) // per_page if total_messages > 0 else 1

# Determine which page to redirect to
redirect_page = current_page
if total_pages == 0 or total_messages == 0:
redirect_page = 1
elif current_page > total_pages:
redirect_page = total_pages

flash(f'Message {message_id} has been deleted.', 'success')
return redirect(url_for('test_table', page=redirect_page))
else:
flash(f'Message {message_id} did not exist.', 'warning')
return redirect(url_for('test_table'))

with app.app_context():
# Test Case 1: Delete from middle page - should stay on same page
db.drop_all()
db.create_all()
for i in range(25): # Create 25 messages (3 pages of 10 each, 5 on last page)
msg = Message(text=f'Message {i+1}')
db.session.add(msg)
db.session.commit()

# Go to page 2 and delete a message
response = client.get('/table?page=2')
assert 'Page 2 of 3' in response.get_data(as_text=True)

# Delete message ID 15 (should be on page 2)
response = client.post('/table/15/delete?page=2', follow_redirects=True)
data = response.get_data(as_text=True)
assert 'Page 2 of 3' in data # Should still be on page 2
assert 'Total: 24' in data # One less message

# Test Case 2: Delete all items from last page - should redirect to previous page
db.drop_all()
db.create_all()
for i in range(21): # Create 21 messages (3 pages: 10, 10, 1)
msg = Message(text=f'Message {i+1}')
db.session.add(msg)
db.session.commit()

# Go to page 3 (last page with 1 item)
response = client.get('/table?page=3')
data = response.get_data(as_text=True)
assert 'Page 3 of 3' in data
assert 'Total: 21' in data

# Delete the only message on page 3
response = client.post('/table/21/delete?page=3', follow_redirects=True)
data = response.get_data(as_text=True)
assert 'Page 2 of 2' in data # Should redirect to page 2
assert 'Total: 20' in data # One less message

# Test Case 3: Delete all messages - should go to page 1
db.drop_all()
db.create_all()
msg = Message(text='Last message')
db.session.add(msg)
db.session.commit()

response = client.post('/table/1/delete', follow_redirects=True)
data = response.get_data(as_text=True)
assert 'Page 1 of' in data # Should be on page 1 (could be "Page 1 of 0" or "Page 1 of 1")
assert 'Total: 0' in data # No messages left
Loading