-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from Ghosts6/oldVersion
Rebase and restructure code + improvement
- Loading branch information
Showing
89 changed files
with
6,660 additions
and
1,583 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.