Skip to content

Commit

Permalink
Merge pull request #1 from Ghosts6/oldVersion
Browse files Browse the repository at this point in the history
Rebase and restructure code + improvement
  • Loading branch information
Ghosts6 authored Dec 1, 2024
2 parents 93e0019 + 8f67aab commit 235ebdc
Show file tree
Hide file tree
Showing 89 changed files with 6,660 additions and 1,583 deletions.
10 changes: 9 additions & 1 deletion .github/workflows/django.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ jobs:

env:
SECRET_KEY: ${{ secrets.SECRET_KEY }}
API_KEY: ${{ secrets.API_KEY }}
API_KEY: ${{ secrets.API_KEY }}
NEWS_API_KEY: ${{ secrets.NEWS_API_KEY }}
WEATHER_API_KEY: ${{ secrets.WEATHER_API_KEY }}
WEATHER_API_KEY_2: ${{ secrets.WEATHER_API_KEY_2 }}

strategy:
max-parallel: 4
Expand All @@ -33,6 +36,11 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install --no-cache-dir -r requirements.txt
- name: Collect static files
run: |
cd backend
python manage.py collectstatic --no-input
- name: Run Tests
run: |
cd backend
python manage.py test
40 changes: 38 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,38 @@
.env
.vscode
# Backend
*.env
.vscode/
__pycache__/
*.pyc
db.sqlite3
log.txt
staticfiles/
cache/*.djcache
*.djcache

# Frontend
node_modules/
build/
dist/
*.log
.pnp/
.pnp.js
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Testing
coverage/

# Production
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

# Miscellaneous
*.swp
.idea/
*.iml
*.lock

399 changes: 222 additions & 177 deletions README.md

Large diffs are not rendered by default.

File renamed without changes.
188 changes: 188 additions & 0 deletions backend/Tests/views_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
from mock import mock_open
import pytest
from django.urls import reverse
from unittest.mock import patch, MagicMock
from rest_framework.test import APIClient
import json

from weather.views import get_timezone_data

@pytest.fixture
def api_client():
return APIClient()

@pytest.mark.django_db
def test_home_view(api_client):
url = reverse('home')
response = api_client.get(url)

assert response.status_code == 200
assert 'user_location_summary' in response.context
assert 'paris_weather_summary' in response.context

@pytest.mark.django_db
def test_search_suggestions_valid(api_client):
url = reverse('search_suggestions')
with patch('builtins.open', mock_open(read_data=json.dumps([
{'name': 'Paris'},
{'name': 'Parma'},
{'name': 'Paradise'}
]))):
response = api_client.get(url, {'city_name': 'par'})
data = response.json()

assert data['success'] is True
assert 'Paris' in data['suggestions']
assert 'Parma' in data['suggestions']
assert 'Paradise' in data['suggestions']

@pytest.mark.django_db
def test_search_suggestions_no_match(api_client):
url = reverse('search_suggestions')
with patch('builtins.open', mock_open(read_data=json.dumps([
{'name': 'Paris'},
{'name': 'Parma'},
{'name': 'Paradise'}
]))):
response = api_client.get(url, {'city_name': 'xyz'})
data = response.json()

assert data['success'] is True
assert len(data['suggestions']) == 0

@pytest.mark.django_db
def test_get_weather_data_valid(api_client):
url = reverse('get_weather_data')

weather_data_mock = {
'cod': 200,
'main': {'temp': 295.15, 'humidity': 80},
'weather': [{'description': 'Clear sky', 'icon': '01d'}],
'wind': {'speed': 5},
'timezone': 3600
}

weatherapi_data_mock = {
'forecast': {
'forecastday': [{
'hour': [{
'time': '2024-11-29 00:00',
'temp_c': 18.0,
'condition': {'text': 'Clear', 'icon': '01d'}
}]
}]
}
}

with patch('requests.get') as mock_get:
mock_get.side_effect = [
MagicMock(status_code=200, json=MagicMock(return_value=weather_data_mock)),
MagicMock(status_code=200, json=MagicMock(return_value=weatherapi_data_mock))
]

response = api_client.get(url, {'city_name': 'Paris'})
data = response.json()

assert response.status_code == 200
assert data['city_name'] == 'Paris'
assert 'temperature' in data
assert 'description' in data
assert len(data['hourly_forecast']) == 1
assert data['hourly_forecast'][0]['time'] == '00:00'
assert data['hourly_forecast'][0]['temperature'] == 18.0

@pytest.mark.django_db
def test_get_weather_data_city_not_found(api_client):
url = reverse('get_weather_data')

weather_data_mock = {'cod': '404'}

with patch('requests.get') as mock_get:
mock_get.return_value = MagicMock(status_code=404, json=MagicMock(return_value=weather_data_mock))

response = api_client.get(url, {'city_name': 'InvalidCity'})
data = response.json()

assert response.status_code == 404
assert data['error_message'] == 'City Not Found'

@pytest.mark.django_db
def test_get_weather_data_missing_city(api_client):
url = reverse('get_weather_data')

response = api_client.get(url, {'city_name': ''})
data = response.json()

assert response.status_code == 400
assert data['error_message'] == 'City name is required'

@pytest.mark.django_db
def test_get_timezone_data_valid():
timezone_data_mock = {'timezone': 'Europe/Paris'}

with patch('requests.get') as mock_get:
mock_get.return_value = MagicMock(status_code=200, json=MagicMock(return_value=timezone_data_mock))

result = get_timezone_data('Paris')

assert result == 'Europe/Paris'

@pytest.mark.django_db
def test_get_timezone_data_invalid():
timezone_data_mock = {}

with patch('requests.get') as mock_get:
mock_get.return_value = MagicMock(status_code=200, json=MagicMock(return_value=timezone_data_mock))

result = get_timezone_data('InvalidCity')

assert result is None

@pytest.mark.django_db
def test_get_timezone_data_exception():
with patch('requests.get') as mock_get:
mock_get.side_effect = Exception("API Error")

result = get_timezone_data('Paris')

assert result is None

@pytest.mark.django_db
def test_get_time_zone_valid(api_client):
url = reverse('get_time_zone')

timezone_data_mock = {'timezone': 'Europe/Paris'}

with patch('requests.get') as mock_get:
mock_get.return_value = MagicMock(status_code=200, json=MagicMock(return_value=timezone_data_mock))

response = api_client.get(url, {'city_name': 'Paris'})
data = response.json()

assert response.status_code == 200
assert data['city_name'] == 'Paris'
assert data['timezone'] == 'Europe/Paris'

@pytest.mark.django_db
def test_get_time_zone_city_not_found(api_client):
url = reverse('get_time_zone')

with patch('requests.get') as mock_get:
mock_get.return_value = MagicMock(status_code=404, json=MagicMock(return_value={}))

response = api_client.get(url, {'city_name': 'InvalidCity'})
data = response.json()

assert response.status_code == 404
assert data['error_message'] == 'Could not fetch timezone data'

@pytest.mark.django_db
def test_get_time_zone_missing_city(api_client):
url = reverse('get_time_zone')

response = api_client.get(url, {'city_name': ''})
data = response.json()

assert response.status_code == 400
assert data['error_message'] == 'City name is required'

10 changes: 6 additions & 4 deletions climate/Template/404.html → backend/climate/Template/404.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@
<link rel="icon" type="image/png" sizes="16x16" href="{% static 'fav/favicon-16x16.png'%}">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<link rel="stylesheet" href="{% static 'css/404.css' %}">
<link rel="stylesheet" href="{% static 'css/output.css' %}">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<title>Error 404</title>
</head>
<body>
<canvas></canvas>
<div class="error">Error 404: Page Not Found</div>
<body class="bg-black bg-cover absolute overflow-hidden">
<canvas class="fixed top-0 left-0"></canvas>
<div class="error fixed top-[40%] left-1/2 -translate-x-1/2 -translate-y-1/2 text-[48px] font-bold text-shadow-error-shadow">
Error 404: Page Not Found
</div>
<script src="{% static 'js/404.js' %}"></script>
</body>
</html>
10 changes: 6 additions & 4 deletions climate/Template/500.html → backend/climate/Template/500.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@
<link rel="icon" type="image/png" sizes="16x16" href="{% static 'fav/favicon-16x16.png'%}">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<link rel="stylesheet" href="{% static 'css/404.css' %}">
<link rel="stylesheet" href="{% static 'css/output.css' %}">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<title>Error 505</title>
</head>
<body>
<canvas></canvas>
<div class="error">Error 500: Unexpected Error :(</div>
<body class="bg-black bg-cover absolute overflow-hidden">
<canvas class="fixed top-0 left-0"></canvas>
<div class="error fixed top-[40%] left-1/2 -translate-x-1/2 -translate-y-1/2 text-[48px] font-bold text-shadow-error-shadow">
Error 500: Unexpected Error :(
</div>
<script src="{% static 'js/404.js' %}"></script>
</body>
</html>
Loading

0 comments on commit 235ebdc

Please sign in to comment.