Permiso de geolocalización
Implementa: web, app
Consume: —
Estado: activa
Última revisión: 2026-05-20T15:30:58Z
# Implementa: web, app
# Consume: —
# Estado: activa
# Última revisión: 2026-05-20T15:30:58Z
# Position: 1
Feature: Permiso de geolocalización
La app necesita la ubicación del usuario para buscar gasolineras cercanas.
La ubicación se captura una sola vez al arrancar — no hay seguimiento continuo.
El usuario puede actualizar su posición recargando la app (pull-to-refresh en
móvil, recarga de página en web).
El nombre de ciudad que aparece en la barra de subtítulo ("SEVILLA") proviene
del campo `station.city` de la mejor estación devuelta por el API — no hay
geocoding inverso de las coordenadas del usuario.
# ---------------------------------------------------------------------------
# Web — Browser Geolocation API
# ---------------------------------------------------------------------------
Scenario: Primera apertura en web — el navegador muestra el prompt
Given el usuario abre la app en un navegador por primera vez
And no hay decisión de permiso previa
When el navegador solicita acceso a la ubicación
Then el usuario ve el prompt nativo del navegador
And si acepta, la app obtiene las coordenadas y carga los resultados
And si rechaza, la app muestra el estado de permiso denegado
Scenario: Permiso denegado pero recuperable en web
Given el usuario denegó el permiso pero puede volver a ser solicitado
# geoPermission === 'prompt' — el navegador puede mostrar el prompt de nuevo
Then la app muestra el estado "Location access denied"
And muestra un botón "Solicitar permiso" que dispara el prompt del navegador
And si el usuario acepta en el prompt, la app inicia la localización
Scenario: Permiso bloqueado permanentemente en Chrome (web)
Given el usuario bloqueó el permiso de forma permanente en Chrome
# geoPermission === 'denied' — navigator.permissions.query devuelve 'denied'
Then la app muestra el estado "Location access denied"
And no muestra el botón "Solicitar permiso" (el prompt no puede volver a aparecer)
And muestra instrucciones específicas para Chrome:
"""
1. Pulsa el icono de candado en la barra de dirección
2. Busca "Ubicación" y cambia a "Permitir"
3. Recarga la página
"""
And muestra un botón "Reintentar" para que el usuario confirme que ya habilitó el permiso
Scenario: Permiso bloqueado permanentemente en Safari (web)
Given el usuario bloqueó el permiso de forma permanente en Safari
Then la app muestra el estado "Location access denied"
And no muestra el botón "Solicitar permiso"
And muestra instrucciones específicas para Safari:
"""
1. Ve a Ajustes del sistema → Privacidad y seguridad → Ubicación
2. Busca Safari y cámbialo a "Mientras se usa"
3. Recarga la página
"""
And muestra un botón "Reintentar"
Scenario: El usuario habilita el permiso tras seguir las instrucciones (web)
Given el usuario ha habilitado el permiso en los ajustes del navegador
When pulsa "Reintentar"
Then la app vuelve a solicitar la ubicación
And si el permiso ya está concedido, carga los resultados sin mostrar el prompt
Scenario: Error de GPS en web (permiso concedido pero fallo técnico)
Given el usuario concedió el permiso de ubicación
When el navegador no puede obtener las coordenadas (timeout u otro error)
Then la app muestra el estado de error de geolocalización
And muestra un botón "Reintentar" que vuelve a llamar a getCurrentPosition
# ---------------------------------------------------------------------------
# App nativa — iOS y Android
# ---------------------------------------------------------------------------
Scenario: Primera apertura en app — solicitud de permiso persistente
Given el usuario abre la app nativa por primera vez
When la app solicita acceso a la ubicación
Then solicita permiso persistente ("Siempre" en iOS, "Siempre" o "Solo mientras se usa" en Android)
# No se solicita "Solo esta vez": el prompt reaparecería en cada sesión
And el usuario decide si concede o deniega
Scenario: Permiso concedido en app
Given el usuario concedió el permiso de ubicación en la app
When abre la app
Then la app obtiene las coordenadas sin mostrar ningún prompt
And carga los resultados directamente
Scenario: Permiso denegado permanentemente en iOS
Given el usuario denegó el permiso en iOS y no puede volver a solicitarse
Then la app muestra el estado "Location access denied"
And muestra instrucciones específicas para iOS:
"""
1. Ve a Ajustes → Privacidad y seguridad → Localización
2. Busca Tanko y selecciona "Siempre" o "Al usar la app"
"""
And muestra un botón "Reintentar" que comprueba si el permiso ya fue habilitado
Scenario: Permiso denegado permanentemente en Android
Given el usuario denegó el permiso en Android y no puede volver a solicitarse
Then la app muestra el estado "Location access denied"
And muestra instrucciones específicas para Android:
"""
1. Ve a Ajustes → Aplicaciones → Tanko → Permisos → Ubicación
2. Selecciona "Permitir siempre" o "Permitir solo mientras se usa"
"""
And muestra un botón "Reintentar"
# ---------------------------------------------------------------------------
# Ciclo de vida de la ubicación (web y app)
# ---------------------------------------------------------------------------
Scenario: La ubicación no se actualiza automáticamente
Given el usuario tiene la app abierta
When se desplaza a otra ubicación sin cerrar la app
Then la app sigue usando las coordenadas capturadas al arrancar
And los resultados no cambian hasta que el usuario recargue
Scenario: El usuario actualiza su ubicación con pull-to-refresh
Given el usuario está en la pantalla principal con resultados cargados
When realiza pull-to-refresh (desliza hacia abajo en móvil o recarga la página)
Then la app vuelve a capturar las coordenadas actuales
And recarga los resultados con la nueva posición
# ---------------------------------------------------------------------------
# Ciudad en la barra de subtítulo
# ---------------------------------------------------------------------------
Scenario: La ciudad mostrada en el subtítulo proviene del API
Given la app ha cargado resultados correctamente
Then la barra de subtítulo muestra el valor de `station.city` de la mejor estación
# No hay geocoding inverso — si la mejor estación está en Sevilla, aparece "SEVILLA"
And mientras los resultados están cargando, la ciudad no se muestra