Skip to content
Draft
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
4 changes: 4 additions & 0 deletions auctions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,7 @@ class Watchlist(models.Model):

def __str__(self):
return f"{self.user} added {self.listing.title} to watchlist"

def toggle(self):
self.active = not self.active
self.save()
6 changes: 3 additions & 3 deletions auctions/templates/auctions/auction.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ <h1 class="auction-title">{{ listing.title }}</h1>
<form action="{% url 'watchlist' listing.id %}" method="post" class="d-inline">
{% csrf_token %}
<button type="submit"
class="btn btn-outline-heart {% if listing in user.watchlist.all %}active{% endif %}"
title="{% if listing in user.watchlist.all %}Remove from Watchlist{% else %}Add to Watchlist{% endif %}">
class="btn btn-outline-heart {% if listing in user.watchlist.filter.active %}active{% endif %}"
title="{% if listing in user.watchlist.filter.active %}Remove from Watchlist{% else %}Add to Watchlist{% endif %}">
<i class="fas fa-heart"></i>
<span class="watchlist-text">
{% if listing in user.watchlist.all %}
{% if listing in user.watchlist.filter.active %}
In Watchlist
{% else %}
Add to Watchlist
Expand Down
2 changes: 1 addition & 1 deletion auctions/templates/auctions/categories.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ <h3>No listings found</h3>
<p>{{ selected_category|default:"No" }} items are currently available</p>
{% if user.is_authenticated %}
<div class="empty-actions">
<a href="{% url 'addAuctions' %}" class="btn btn-primary btn-lg">
<a href="{% url 'new_auction' %}" class="btn btn-primary btn-lg">
<i class="fas fa-plus-circle"></i>Create New Auction
</a>
</div>
Expand Down
2 changes: 1 addition & 1 deletion auctions/templates/auctions/components/footer.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ <h5 class="footer-heading">Quick Links</h5>
</a>
</li>
<li>
<a href="{% url 'addAuctions' %}">
<a href="{% url 'new_auction' %}">
<i class="fas fa-plus-circle me-2"></i>Create
Listing
</a>
Expand Down
4 changes: 2 additions & 2 deletions auctions/templates/auctions/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ <h2 class="display-5 display-md-4 fw-bold">
</div>
{% if user.is_authenticated %}
<div class="col-12 col-md-auto mt-2 mt-md-0">
<a href="{% url 'addAuctions' %}" class="btn btn-primary btn-lg d-flex align-items-center justify-content-center justify-content-md-start">
<a href="{% url 'new_auction' %}" class="btn btn-primary btn-lg d-flex align-items-center justify-content-center justify-content-md-start">
<i class="fas fa-plus-circle me-2"></i>Create New Auction
</a>
</div>
Expand Down Expand Up @@ -78,7 +78,7 @@ <h2 class="display-5 display-md-4 fw-bold">
<h3 class="h4 fw-bold">No active listings at the moment</h3>
<p class=" mb-4">Be the first to create an auction and start earning!</p>
{% if user.is_authenticated %}
<a href="{% url 'addAuctions' %}" class="btn btn-primary btn-lg">
<a href="{% url 'new_auction' %}" class="btn btn-primary btn-lg">
<i class="fas fa-plus-circle me-2"></i>Create New Auction
</a>
{% else %}
Expand Down
2 changes: 1 addition & 1 deletion auctions/templates/auctions/newAuctions.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ <h2 class="card-title text-center mb-4">
<i class="fas fa-plus-circle text-primary me-2"></i>Create New Auction
</h2>

<form action="{% url 'addAuctions' %}" method="post" id="form-auction" class="needs-validation">
<form action="{% url 'new_auction' %}" method="post" id="form-auction" class="needs-validation">
{% csrf_token %}

<div class="form-group mb-4">
Expand Down
1 change: 0 additions & 1 deletion auctions/tests.py

This file was deleted.

Empty file added auctions/tests/__init__.py
Empty file.
52 changes: 52 additions & 0 deletions auctions/tests/factories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import factory
from factory.django import DjangoModelFactory
from auctions.models import User, Listing, Bid, Comment, Watchlist


class UserFactory(DjangoModelFactory):
class Meta:
model = User
django_get_or_create = ("username",)

username = factory.Faker("user_name")
email = factory.Faker("email")
password = factory.PostGenerationMethodCall("set_password", "testpassword")


class ListingFactory(DjangoModelFactory):
class Meta:
model = Listing

title = factory.Faker("sentence", nb_words=4)
description = factory.Faker("text")
starting_bid = factory.Faker(
"pydecimal", left_digits=3, right_digits=2, positive=True
)
user = factory.SubFactory(UserFactory)


class BidFactory(DjangoModelFactory):
class Meta:
model = Bid

amount = factory.Faker("pydecimal", left_digits=3, right_digits=2, positive=True)
user = factory.SubFactory(UserFactory)
listing = factory.SubFactory(ListingFactory)


class CommentFactory(DjangoModelFactory):
class Meta:
model = Comment

text = factory.Faker("text")
user = factory.SubFactory(UserFactory)
listing = factory.SubFactory(ListingFactory)


class WatchlistFactory(DjangoModelFactory):
class Meta:
model = Watchlist

user = factory.SubFactory(UserFactory)
listing = factory.SubFactory(ListingFactory)
active = True
94 changes: 94 additions & 0 deletions auctions/tests/test_forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
from django.test import TestCase
from auctions.forms import ListingForm, BidForm, CommentForm
from .factories import UserFactory


class ListingFormTest(TestCase):
def test_valid_form(self):
user = UserFactory()
form_data = {
"title": "Test Listing",
"description": "This is a test description.",
"starting_bid": 10.00,
"image": "http://example.com/image.jpg",
"category": "Other",
}
form = ListingForm(data=form_data)
self.assertTrue(form.is_valid())

def test_empty_title(self):
form_data = {"title": ""}
form = ListingForm(data=form_data)
self.assertFalse(form.is_valid())
self.assertIn("title", form.errors)

def test_duplicate_title(self):
user = UserFactory()
from auctions.models import Listing

Listing.objects.create(title="Test Listing", user=user, starting_bid=10.00)
form_data = {"title": "Test Listing"}
form = ListingForm(data=form_data)
self.assertFalse(form.is_valid())
self.assertIn("title", form.errors)

def test_empty_description(self):
form_data = {"description": ""}
form = ListingForm(data=form_data)
self.assertFalse(form.is_valid())
self.assertIn("description", form.errors)

def test_empty_starting_bid(self):
form_data = {"starting_bid": None}
form = ListingForm(data=form_data)
self.assertFalse(form.is_valid())
self.assertIn("starting_bid", form.errors)

def test_negative_starting_bid(self):
form_data = {"starting_bid": -10.00}
form = ListingForm(data=form_data)
self.assertFalse(form.is_valid())
self.assertIn("starting_bid", form.errors)

def test_invalid_image_url(self):
form_data = {"image": "not a url"}
form = ListingForm(data=form_data)
self.assertFalse(form.is_valid())
self.assertIn("image", form.errors)


class BidFormTest(TestCase):
def test_valid_form(self):
form_data = {"amount": 10.00}
form = BidForm(data=form_data)
self.assertTrue(form.is_valid())

def test_empty_amount(self):
form_data = {"amount": None}
form = BidForm(data=form_data)
self.assertFalse(form.is_valid())
self.assertIn("amount", form.errors)

def test_zero_amount(self):
form_data = {"amount": 0}
form = BidForm(data=form_data)
self.assertFalse(form.is_valid())
self.assertIn("amount", form.errors)

def test_negative_amount(self):
form_data = {"amount": -10.00}
form = BidForm(data=form_data)
self.assertFalse(form.is_valid())
self.assertIn("amount", form.errors)


class CommentFormTest(TestCase):
def test_valid_form(self):
form_data = {"text": "This is a test comment."}
form = CommentForm(data=form_data)
self.assertTrue(form.is_valid())

def test_empty_text(self):
form_data = {"text": ""}
form = CommentForm(data=form_data)
self.assertTrue(form.is_valid()) # empty comment is allowed
49 changes: 49 additions & 0 deletions auctions/tests/test_integration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from decimal import Decimal
from django.test import TestCase, Client
from django.urls import reverse
from auctions.models import User, Listing
from .factories import UserFactory


class AuctionFlowTest(TestCase):
def setUp(self):
self.client = Client()
self.user1 = UserFactory(username="user1")
self.user1.set_password("testpassword")
self.user1.save()
self.user2 = UserFactory(username="user2")
self.user2.set_password("testpassword")
self.user2.save()

def test_full_auction_flow(self):
# 1. user1 creates a listing
self.client.login(username="user1", password="testpassword")
response = self.client.post(
reverse("new_auction"),
{
"title": "Integration Test Listing",
"description": "A listing for integration testing.",
"starting_bid": "10.00",
"category": "Other",
},
)
self.assertEqual(response.status_code, 302)
listing = Listing.objects.get(title="Integration Test Listing")
self.assertEqual(listing.user, self.user1)

# 2. user2 places a bid
self.client.login(username="user2", password="testpassword")
response = self.client.post(
reverse("bid", args=[listing.id]), {"amount": "15.00"}
)
self.assertEqual(response.status_code, 302)
listing.refresh_from_db()
self.assertEqual(listing.current_bid, Decimal("15.00"))

# 3. user1 closes the auction
self.client.login(username="user1", password="testpassword")
response = self.client.post(reverse("close_auction", args=[listing.id]))
self.assertEqual(response.status_code, 302)
listing.refresh_from_db()
self.assertFalse(listing.active)
self.assertEqual(listing.winner, self.user2)
78 changes: 78 additions & 0 deletions auctions/tests/test_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
from decimal import Decimal
from django.core.exceptions import ValidationError
from django.test import TestCase
from auctions.models import Listing, Bid, Comment, Watchlist
from .factories import (
UserFactory,
ListingFactory,
BidFactory,
CommentFactory,
WatchlistFactory,
)


class ListingModelTest(TestCase):
def test_string_representation(self):
listing = ListingFactory(title="My Test Listing", starting_bid=Decimal("10.00"))
self.assertEqual(str(listing), "My Test Listing - 10.00")

def test_place_bid_successfully(self):
listing = ListingFactory(
starting_bid=Decimal("10.00"), current_bid=Decimal("10.00")
)
user = UserFactory()
listing.place_bid(user, Decimal("12.00"))
self.assertEqual(listing.current_bid, Decimal("12.00"))
self.assertEqual(listing.bids.count(), 1)
self.assertEqual(listing.bids.first().user, user)
self.assertEqual(listing.bids.first().amount, Decimal("12.00"))

def test_place_bid_with_lower_amount(self):
listing = ListingFactory(
starting_bid=Decimal("10.00"), current_bid=Decimal("12.00")
)
user = UserFactory()
with self.assertRaises(ValidationError):
listing.place_bid(user, Decimal("11.00"))

def test_place_bid_with_equal_amount(self):
listing = ListingFactory(
starting_bid=Decimal("10.00"), current_bid=Decimal("12.00")
)
user = UserFactory()
with self.assertRaises(ValidationError):
listing.place_bid(user, Decimal("12.00"))


class BidModelTest(TestCase):
def test_string_representation(self):
user = UserFactory(username="testuser")
listing = ListingFactory(title="Test Listing")
bid = BidFactory(user=user, listing=listing, amount=Decimal("15.00"))
self.assertEqual(str(bid), "testuser bid 15.00 on Test Listing")


class CommentModelTest(TestCase):
def test_string_representation(self):
user = UserFactory(username="commenter")
listing = ListingFactory(title="Another Listing")
comment = CommentFactory(user=user, listing=listing)
self.assertEqual(str(comment), "commenter commented on Another Listing")


class WatchlistModelTest(TestCase):
def test_string_representation(self):
user = UserFactory(username="watcher")
listing = ListingFactory(title="Watchlist Item")
watchlist_item = WatchlistFactory(user=user, listing=listing)
self.assertEqual(
str(watchlist_item), "watcher added Watchlist Item to watchlist"
)

def test_toggle_watchlist(self):
watchlist_item = WatchlistFactory(active=True)
self.assertTrue(watchlist_item.active)
watchlist_item.toggle()
self.assertFalse(watchlist_item.active)
watchlist_item.toggle()
self.assertTrue(watchlist_item.active)
24 changes: 24 additions & 0 deletions auctions/tests/test_templates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from django.test import TestCase, Client
from django.urls import reverse
from .factories import ListingFactory, UserFactory


class TemplateTest(TestCase):
def setUp(self):
self.client = Client()
self.user = UserFactory()

def test_index_template_displays_listings(self):
ListingFactory.create_batch(3, title="Test Listing")
response = self.client.get(reverse("index"))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Test Listing", count=6)

def test_auction_template_displays_listing_details(self):
listing = ListingFactory(
title="Detailed Listing", description="Detailed description."
)
response = self.client.get(reverse("listing", args=[listing.id]))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Detailed Listing")
self.assertContains(response, "Detailed description.")
Loading