sky form: clear timezone field on new place pick so TZ auto-redetects from coords — TDD
selectPlace + geolocation now zero out tzInput.value & tzHint before schedulePreview, so the existing `if (!tzInput.value && data.timezone)` backfill in schedulePreview's success path actually fires when the user changes location after a saved sky exists. Without the clear, the saved/previous TZ stayed pinned & the chart was recomputed against the wrong timezone. Fix mirrored across sky.html (Dashsky), _applet-my-sky.html (My Sky applet entry form), and _sky_overlay.html (PICK SKY in-room overlay). New FT MySkyTimezoneRefreshTest.test_changing_place_refreshes_auto_detected_timezone seeds a user w. saved Baltimore/America/New_York, mocks Nominatim + sky/preview to return Camarillo + America/Los_Angeles, picks the suggestion, and asserts the TZ field updates. Code architected by Disco DeDisco <discodedisco@outlook.com> Git commit message Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,8 @@ to their account (stored on the User model, independent of any game room).
|
|||||||
|
|
||||||
import json as _json
|
import json as _json
|
||||||
import unittest
|
import unittest
|
||||||
|
import zoneinfo
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
|
|
||||||
@@ -163,7 +165,7 @@ class MySkyAppletWheelTest(FunctionalTest):
|
|||||||
)
|
)
|
||||||
self.gamer = User.objects.create(email="stargazer@test.io")
|
self.gamer = User.objects.create(email="stargazer@test.io")
|
||||||
self.gamer.sky_chart_data = _CHART_FIXTURE
|
self.gamer.sky_chart_data = _CHART_FIXTURE
|
||||||
self.gamer.sky_birth_place = "Lindenwold, NJ, US"
|
self.gamer.sky_birth_place = "Baltimore, MD, US"
|
||||||
self.gamer.save()
|
self.gamer.save()
|
||||||
|
|
||||||
# ── T3 ───────────────────────────────────────────────────────────────────
|
# ── T3 ───────────────────────────────────────────────────────────────────
|
||||||
@@ -297,6 +299,79 @@ class MySkyAppletFormTest(FunctionalTest):
|
|||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
class MySkyTimezoneRefreshTest(FunctionalTest):
|
||||||
|
"""Selecting a new birth place must refresh the auto-detected timezone."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
Applet.objects.get_or_create(
|
||||||
|
slug="my-sky",
|
||||||
|
defaults={"name": "My Sky", "grid_cols": 6, "grid_rows": 6, "context": "dashboard"},
|
||||||
|
)
|
||||||
|
self.gamer = User.objects.create(email="stargazer@test.io")
|
||||||
|
self.gamer.sky_chart_data = _CHART_FIXTURE
|
||||||
|
self.gamer.sky_birth_place = "Baltimore, MD, US"
|
||||||
|
self.gamer.sky_birth_tz = "America/New_York"
|
||||||
|
self.gamer.sky_birth_lat = 39.2904
|
||||||
|
self.gamer.sky_birth_lon = -76.6122
|
||||||
|
self.gamer.sky_birth_dt = datetime(
|
||||||
|
1990, 6, 15, 12, 0, tzinfo=zoneinfo.ZoneInfo("UTC")
|
||||||
|
)
|
||||||
|
self.gamer.save()
|
||||||
|
self.sky_url = self.live_server_url + "/dashboard/sky/"
|
||||||
|
|
||||||
|
def test_changing_place_refreshes_auto_detected_timezone(self):
|
||||||
|
"""Picking a new place via the suggestion dropdown must update the
|
||||||
|
timezone field to the new place's auto-detected TZ rather than sticking
|
||||||
|
on the previously saved value."""
|
||||||
|
self.create_pre_authenticated_session("stargazer@test.io")
|
||||||
|
self.browser.get(self.sky_url)
|
||||||
|
|
||||||
|
# 1. Initial state: TZ field shows the saved America/New_York
|
||||||
|
tz_input = self.wait_for(lambda: self.browser.find_element(By.ID, "id_nf_tz"))
|
||||||
|
self.assertEqual(tz_input.get_attribute("value"), "America/New_York")
|
||||||
|
|
||||||
|
# 2. Mock Nominatim search + sky/preview to return Camarillo / Pacific TZ
|
||||||
|
camarillo_chart = dict(_CHART_FIXTURE)
|
||||||
|
camarillo_chart["timezone"] = "America/Los_Angeles"
|
||||||
|
self.browser.execute_script("""
|
||||||
|
const NEW_CHART = """ + _json.dumps(camarillo_chart) + """;
|
||||||
|
window._origFetch = window.fetch;
|
||||||
|
window.fetch = function(url, opts) {
|
||||||
|
if (typeof url === 'string' && url.includes('nominatim.openstreetmap.org/search')) {
|
||||||
|
return Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
json: () => Promise.resolve([{
|
||||||
|
display_name: 'Camarillo, Ventura County, California, US',
|
||||||
|
lat: '34.2176', lon: '-119.0384',
|
||||||
|
}]),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (typeof url === 'string' && url.includes('/sky/preview')) {
|
||||||
|
return Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
json: () => Promise.resolve(NEW_CHART),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return window._origFetch(url, opts);
|
||||||
|
};
|
||||||
|
""")
|
||||||
|
|
||||||
|
# 3. Type into the place input → click first Nominatim suggestion
|
||||||
|
place_input = self.browser.find_element(By.ID, "id_nf_place")
|
||||||
|
place_input.clear()
|
||||||
|
place_input.send_keys("Cam")
|
||||||
|
suggestion = self.wait_for_slow(lambda: self.browser.find_element(
|
||||||
|
By.CSS_SELECTOR, ".sky-suggestion-item"
|
||||||
|
))
|
||||||
|
suggestion.click()
|
||||||
|
|
||||||
|
# 4. After preview resolves, TZ field should show the new auto-detected TZ
|
||||||
|
self.wait_for(lambda: self.assertEqual(
|
||||||
|
tz_input.get_attribute("value"), "America/Los_Angeles"
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
class MySkyWheelConjunctionTest(FunctionalTest):
|
class MySkyWheelConjunctionTest(FunctionalTest):
|
||||||
"""Tick lines, z-raise, and dual tooltip for conjunct planets."""
|
"""Tick lines, z-raise, and dual tooltip for conjunct planets."""
|
||||||
|
|
||||||
|
|||||||
@@ -214,6 +214,8 @@
|
|||||||
placeInput.value = place.display_name;
|
placeInput.value = place.display_name;
|
||||||
latInput.value = parseFloat(place.lat).toFixed(4);
|
latInput.value = parseFloat(place.lat).toFixed(4);
|
||||||
lonInput.value = parseFloat(place.lon).toFixed(4);
|
lonInput.value = parseFloat(place.lon).toFixed(4);
|
||||||
|
tzInput.value = '';
|
||||||
|
tzHint.textContent = '';
|
||||||
hideSuggestions();
|
hideSuggestions();
|
||||||
_saveForm();
|
_saveForm();
|
||||||
schedulePreview();
|
schedulePreview();
|
||||||
@@ -231,6 +233,8 @@
|
|||||||
(pos) => {
|
(pos) => {
|
||||||
latInput.value = pos.coords.latitude.toFixed(4);
|
latInput.value = pos.coords.latitude.toFixed(4);
|
||||||
lonInput.value = pos.coords.longitude.toFixed(4);
|
lonInput.value = pos.coords.longitude.toFixed(4);
|
||||||
|
tzInput.value = '';
|
||||||
|
tzHint.textContent = '';
|
||||||
fetch(
|
fetch(
|
||||||
`https://nominatim.openstreetmap.org/reverse?format=json&lat=${latInput.value}&lon=${lonInput.value}`,
|
`https://nominatim.openstreetmap.org/reverse?format=json&lat=${latInput.value}&lon=${lonInput.value}`,
|
||||||
{ headers: { 'User-Agent': USER_AGENT } }
|
{ headers: { 'User-Agent': USER_AGENT } }
|
||||||
|
|||||||
@@ -184,6 +184,8 @@
|
|||||||
placeInput.value = place.display_name;
|
placeInput.value = place.display_name;
|
||||||
latInput.value = parseFloat(place.lat).toFixed(4);
|
latInput.value = parseFloat(place.lat).toFixed(4);
|
||||||
lonInput.value = parseFloat(place.lon).toFixed(4);
|
lonInput.value = parseFloat(place.lon).toFixed(4);
|
||||||
|
tzInput.value = '';
|
||||||
|
tzHint.textContent = '';
|
||||||
hideSuggestions();
|
hideSuggestions();
|
||||||
schedulePreview();
|
schedulePreview();
|
||||||
}
|
}
|
||||||
@@ -200,6 +202,8 @@
|
|||||||
(pos) => {
|
(pos) => {
|
||||||
latInput.value = pos.coords.latitude.toFixed(4);
|
latInput.value = pos.coords.latitude.toFixed(4);
|
||||||
lonInput.value = pos.coords.longitude.toFixed(4);
|
lonInput.value = pos.coords.longitude.toFixed(4);
|
||||||
|
tzInput.value = '';
|
||||||
|
tzHint.textContent = '';
|
||||||
fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${latInput.value}&lon=${lonInput.value}`, {
|
fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${latInput.value}&lon=${lonInput.value}`, {
|
||||||
headers: { 'User-Agent': USER_AGENT },
|
headers: { 'User-Agent': USER_AGENT },
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -246,6 +246,8 @@
|
|||||||
placeInput.value = place.display_name;
|
placeInput.value = place.display_name;
|
||||||
latInput.value = parseFloat(place.lat).toFixed(4);
|
latInput.value = parseFloat(place.lat).toFixed(4);
|
||||||
lonInput.value = parseFloat(place.lon).toFixed(4);
|
lonInput.value = parseFloat(place.lon).toFixed(4);
|
||||||
|
tzInput.value = '';
|
||||||
|
tzHint.textContent = '';
|
||||||
hideSuggestions();
|
hideSuggestions();
|
||||||
_saveForm();
|
_saveForm();
|
||||||
schedulePreview();
|
schedulePreview();
|
||||||
@@ -263,6 +265,8 @@
|
|||||||
(pos) => {
|
(pos) => {
|
||||||
latInput.value = pos.coords.latitude.toFixed(4);
|
latInput.value = pos.coords.latitude.toFixed(4);
|
||||||
lonInput.value = pos.coords.longitude.toFixed(4);
|
lonInput.value = pos.coords.longitude.toFixed(4);
|
||||||
|
tzInput.value = '';
|
||||||
|
tzHint.textContent = '';
|
||||||
fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${latInput.value}&lon=${lonInput.value}`, {
|
fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${latInput.value}&lon=${lonInput.value}`, {
|
||||||
headers: { 'User-Agent': USER_AGENT },
|
headers: { 'User-Agent': USER_AGENT },
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user