File size: 5,227 Bytes
742ea3f
7951739
 
 
 
 
 
 
 
 
6754f1c
7951739
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6754f1c
 
7951739
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
"""Unit tests for Profile models and repositories."""

from __future__ import annotations

from datetime import date
from decimal import Decimal

import pytest
from django.db import IntegrityError

from apps.profiles.constants import COST_PER_CUBIC_YARD, ICE_PER_FOOT
from apps.profiles.models import DailyProgress, Profile, WallSection


@pytest.mark.django_db
class TestProfileModel:
    """Test Profile model functionality."""

    def test_create_profile_success(self) -> None:
        """Test creating a profile with valid data."""
        profile = Profile.objects.create(
            name="Northern Watch",
            team_lead="Jon Snow",
            is_active=True,
        )

        assert profile.id is not None
        assert profile.name == "Northern Watch"
        assert profile.team_lead == "Jon Snow"
        assert profile.is_active is True
        assert profile.created_at is not None
        assert profile.updated_at is not None

    def test_profile_name_unique(self) -> None:
        """Test profile name must be unique."""
        Profile.objects.create(name="Northern Watch", team_lead="Jon Snow")

        with pytest.raises(IntegrityError):
            Profile.objects.create(name="Northern Watch", team_lead="Samwell Tarly")

    def test_profile_str_representation(self) -> None:
        """Test profile string representation."""
        profile = Profile.objects.create(name="Northern Watch", team_lead="Jon Snow")

        assert str(profile) == "Northern Watch (led by Jon Snow)"


@pytest.mark.django_db
class TestWallSectionModel:
    """Test WallSection model functionality."""

    def test_create_wall_section_success(self) -> None:
        """Test creating a wall section with valid data."""
        profile = Profile.objects.create(name="Northern Watch", team_lead="Jon Snow")
        wall_section = WallSection.objects.create(
            profile=profile,
            section_name="Tower 1-2",
        )

        assert wall_section.id is not None
        assert wall_section.profile == profile
        assert wall_section.section_name == "Tower 1-2"

    def test_wall_section_str_representation(self) -> None:
        """Test wall section string representation."""
        profile = Profile.objects.create(name="Northern Watch", team_lead="Jon Snow")
        wall_section = WallSection.objects.create(
            profile=profile,
            section_name="Tower 1-2",
        )

        assert str(wall_section) == "Tower 1-2 (Northern Watch)"


@pytest.mark.django_db
class TestDailyProgressModel:
    """Test DailyProgress model functionality."""

    def test_create_daily_progress_with_calculated_values(self) -> None:
        """Test creating daily progress with explicitly calculated ice and cost values."""
        profile = Profile.objects.create(name="Northern Watch", team_lead="Jon Snow")
        wall_section = WallSection.objects.create(
            profile=profile,
            section_name="Tower 1-2",
        )

        feet_built = Decimal("10.00")
        ice_cubic_yards = feet_built * ICE_PER_FOOT  # 10 × 195 = 1950
        cost_gold_dragons = ice_cubic_yards * COST_PER_CUBIC_YARD  # 1950 × 1900 = 3,705,000

        progress = DailyProgress.objects.create(
            wall_section=wall_section,
            date=date(2025, 10, 20),
            feet_built=feet_built,
            ice_cubic_yards=ice_cubic_yards,
            cost_gold_dragons=cost_gold_dragons,
        )

        assert progress.ice_cubic_yards == Decimal("1950.00")
        assert progress.cost_gold_dragons == Decimal("3705000.00")

    def test_daily_progress_unique_per_wall_section_and_date(self) -> None:
        """Test only one progress entry allowed per wall section per day."""
        profile = Profile.objects.create(name="Northern Watch", team_lead="Jon Snow")
        wall_section = WallSection.objects.create(
            profile=profile,
            section_name="Tower 1-2",
        )

        DailyProgress.objects.create(
            wall_section=wall_section,
            date=date(2025, 10, 20),
            feet_built=Decimal("10.00"),
            ice_cubic_yards=Decimal("1950.00"),
            cost_gold_dragons=Decimal("3705000.00"),
        )

        with pytest.raises(IntegrityError):
            DailyProgress.objects.create(
                wall_section=wall_section,
                date=date(2025, 10, 20),
                feet_built=Decimal("5.00"),
                ice_cubic_yards=Decimal("975.00"),
                cost_gold_dragons=Decimal("1852500.00"),
            )

    def test_daily_progress_str_representation(self) -> None:
        """Test daily progress string representation."""
        profile = Profile.objects.create(name="Northern Watch", team_lead="Jon Snow")
        wall_section = WallSection.objects.create(
            profile=profile,
            section_name="Tower 1-2",
        )

        progress = DailyProgress.objects.create(
            wall_section=wall_section,
            date=date(2025, 10, 20),
            feet_built=Decimal("10.00"),
            ice_cubic_yards=Decimal("1950.00"),
            cost_gold_dragons=Decimal("3705000.00"),
        )

        assert str(progress) == "Tower 1-2: 10.00 ft on 2025-10-20"