passerelle/tests/test_okina.py

2005 lines
68 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
from unittest import mock
import pytest
from django.contrib.contenttypes.models import ContentType
import tests.utils
from passerelle.apps.okina.models import Okina
from passerelle.base.models import AccessRight, ApiUser
CITIES = '''[ {
"city" : 83355,
"cityObject" : {
"id" : 83355,
"insee" : "36005",
"nameCity" : "ARDENTES",
"zipCode" : "36120",
"nameCityRouting" : "ARDENTES",
"line5" : null
}
}, {
"city" : 80237,
"cityObject" : {
"id" : 80237,
"insee" : "36044",
"nameCity" : "CHATEAUROUX",
"zipCode" : "36000",
"nameCityRouting" : "CHATEAUROUX",
"line5" : null
}
} ]
'''
# new API (march 2020)
CITIES_NEW = '''[
{
"id": 83355,
"insee": "36005",
"name": "ARDENTES",
"zipCode": "36120",
"nameCityRouting": null,
"line5": null,
"latitude": null,
"longitude": null,
"geoJson": null
}
]
'''
CLASSES = '''
[
{
"id": 1,
"label": "École maternelle - Petite section"
},
{
"id": 2,
"label": "École maternelle - Moyenne section"
},
{
"id": 4,
"label": "École élémentaire CP"
},
{
"id": 5,
"label": "École élémentaire CE 1"
}
]
'''
INSTITUTIONS = '''[ {
"id" : 276,
"schoolEstablishment" : {
"uai" : "0360155Y",
"uaiLabel" : "Ecole élémentaire Saint-Martin",
"mainTitle" : "ECOLE ELEMENTAIRE PUBLIQUE",
"type" : "Public",
"address" : "RUE CALMETTE ET GUERIN",
"zipCode" : "36120",
"cityName" : "ARDENTES",
"locationX" : "1.82965415466176",
"locationY" : "46.740247926141706",
"nature" : "151",
"natureTitle" : "Ecole élémentaire"
},
"schoolEstablishmentUai" : "0360155Y",
"zipAndCity" : "36120 - ARDENTES",
"institutionContacts" : [ ]
}, {
"id" : 277,
"schoolEstablishment" : {
"uai" : "0360048G",
"uaiLabel" : "Collège Touvent",
"mainTitle" : "COLLEGE",
"type" : "Public",
"address" : "4 ALLÉE DES LAURIERS",
"zipCode" : "36007",
"cityName" : "CHATEAUROUX CEDEX",
"locationX" : "1.6926355997775921",
"locationY" : "46.791332586468016",
"nature" : "340",
"natureTitle" : "Collège"
},
"schoolEstablishmentUai" : "0360048G",
"zipAndCity" : "36007 - CHATEAUROUX CEDEX",
"institutionContacts" : [ ]
} ]
'''
# new API (march 2020)
INSTITUTIONS_NEW = '''[ {
"id" : 276,
"schoolEstablishment" : {
"uai" : "0360155Y",
"uaiLabel" : "Ecole élémentaire Saint-Martin",
"type" : "Public",
"address" : "Rue Calmette et Guérin",
"zipCode" : "36120",
"codeCity" : "36005",
"cityName" : "Ardentes",
"locationX" : "1.8296541547236063",
"locationY" : "46.74024796567764",
"nature" : "1000",
"natureTitle" : "Ecole",
"restoration" : true,
"accommodation" : false,
"ulis" : false,
"segpa" : false,
"sirenSiret" : "21360005900033",
"webSite" : null,
"phone" : "254362184",
"fax" : "",
"email" : "ec-saint-martin-ardentes@ac-orleans-tours.fr",
"departmentLabel" : "Indre",
"academyLabel" : "Orléans-Tours",
"regionLabel" : "Centre-Val de Loire",
"schoolSectionList" : [ ],
"schoolEstablishmentTypeInfos" : [ {
"key" : "ecole_elementaire",
"value" : "École élémentaire"
} ]
},
"schoolEstablishmentDisplayName" : "Ecole élémentaire Saint-Martin",
"schoolEstablishmentUai" : "0360155Y",
"zipAndCity" : "36120 - Ardentes",
"withContract" : true,
"institutionContacts" : [ ],
"institutionTimes" : [ {
"id" : 27,
"day" : "MONDAY",
"way" : "WAY_TO",
"time" : "08:46:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 28,
"day" : "MONDAY",
"way" : "WAY_BACK",
"time" : "16:30:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 29,
"day" : "TUESDAY",
"way" : "WAY_TO",
"time" : "08:46:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 30,
"day" : "TUESDAY",
"way" : "WAY_BACK",
"time" : "16:30:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 31,
"day" : "THURSDAY",
"way" : "WAY_TO",
"time" : "08:46:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 32,
"day" : "THURSDAY",
"way" : "WAY_BACK",
"time" : "16:30:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 33,
"day" : "FRIDAY",
"way" : "WAY_TO",
"time" : "08:46:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 34,
"day" : "FRIDAY",
"way" : "WAY_BACK",
"time" : "16:30:00",
"institutionId" : 0,
"timeString" : null
} ],
"cities" : null,
"optionsDerogatory" : [ ],
"institutionCenterName" : "ARDENTES",
"institutionCenterId" : 3,
"customLocationX" : "1.8296541547236063",
"customLocationY" : "46.74024796567764"
}, {
"id" : 277,
"schoolEstablishment" : {
"uai" : "0360048G",
"uaiLabel" : "Collège Touvent",
"type" : "Public",
"address" : "4 allée des Lauriers",
"zipCode" : "36000",
"codeCity" : "36044",
"cityName" : "Châteauroux",
"locationX" : "1.6926355997775921",
"locationY" : "46.791332586468016",
"nature" : "340",
"natureTitle" : "Collège",
"restoration" : false,
"accommodation" : false,
"ulis" : true,
"segpa" : false,
"sirenSiret" : "19360048300013",
"webSite" : null,
"phone" : "02 54 34 03 30",
"fax" : "02 54 08 01 09",
"email" : "ce.0360048g@ac-orleans-tours.fr",
"departmentLabel" : "Indre",
"academyLabel" : "Orléans-Tours",
"regionLabel" : "Centre-Val de Loire",
"schoolSectionList" : [ {
"key" : "section_sport",
"name" : "Section sport"
} ],
"schoolEstablishmentTypeInfos" : [ ]
},
"schoolEstablishmentDisplayName" : "Collège Touvent",
"schoolEstablishmentUai" : "0360048G",
"zipAndCity" : "36000 - Châteauroux",
"withContract" : true,
"institutionContacts" : [ ],
"institutionTimes" : [ {
"id" : 249,
"day" : "MONDAY",
"way" : "WAY_TO",
"time" : "08:20:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 250,
"day" : "MONDAY",
"way" : "WAY_BACK",
"time" : "17:05:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 251,
"day" : "TUESDAY",
"way" : "WAY_TO",
"time" : "08:20:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 252,
"day" : "TUESDAY",
"way" : "WAY_BACK",
"time" : "17:05:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 253,
"day" : "WEDNESDAY",
"way" : "WAY_TO",
"time" : "07:50:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 254,
"day" : "WEDNESDAY",
"way" : "WAY_BACK",
"time" : "12:05:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 255,
"day" : "THURSDAY",
"way" : "WAY_TO",
"time" : "08:20:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 256,
"day" : "THURSDAY",
"way" : "WAY_BACK",
"time" : "17:05:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 257,
"day" : "FRIDAY",
"way" : "WAY_TO",
"time" : "08:20:00",
"institutionId" : 0,
"timeString" : null
}, {
"id" : 258,
"day" : "FRIDAY",
"way" : "WAY_BACK",
"time" : "17:05:00",
"institutionId" : 0,
"timeString" : null
} ],
"cities" : null,
"optionsDerogatory" : [ ],
"institutionCenterName" : "CHATEAUROUX",
"institutionCenterId" : 2,
"customLocationX" : "1.6926355997775921",
"customLocationY" : "46.791332586468016"
} ]
'''
SEARCH = '''[ {
"id" : 3312,
"stop_point_id" : 1498,
"name" : "Le Grand Verger",
"latitude" : 46.8444186,
"longitude" : 1.708197,
"bearing" : 0.0,
"position" : 6,
"forBoarding" : null,
"forAlighting" : null,
"colorUsage" : null,
"isRecommended" : false,
"titreRelaisId" : null,
"networkType" : "SCHOLAR",
"commercial_stop_area" : 3312,
"commercial_name" : "Le Grand Verger",
"liaisons" : [ ],
"registrationNumber" : "36063_009",
"cityCode" : "36063",
"cityName" : "Déols",
"zipCode" : "36130",
"isDuplicatedCompute" : 0,
"nbClosedStopAreas" : null,
"isValidated" : null,
"isUnique" : null,
"isDuplicated" : null,
"network" : {
"id" : 2,
"name" : "réseau scolaire",
"supprime" : false,
"networkType" : "SCHOLAR"
},
"external_ref" : null,
"distanceBetweenPreviousStopCalculated" : 0.0,
"distanceBetweenPreviousStopReal" : null
}, {
"id" : 3311,
"stop_point_id" : 1499,
"name" : "Jean Bizet U",
"latitude" : 46.8359017,
"longitude" : 1.7045139,
"bearing" : 0.0,
"position" : 7,
"forBoarding" : null,
"forAlighting" : null,
"colorUsage" : null,
"isRecommended" : true,
"titreRelaisId" : null,
"networkType" : "SCHOLAR",
"commercial_stop_area" : 3311,
"commercial_name" : "Jean Bizet U",
"liaisons" : [ ],
"registrationNumber" : "36063_008",
"cityCode" : "36063",
"cityName" : "Déols",
"zipCode" : "36130",
"isDuplicatedCompute" : 0,
"nbClosedStopAreas" : null,
"isValidated" : null,
"isUnique" : null,
"isDuplicated" : null,
"network" : {
"id" : 2,
"name" : "réseau scolaire",
"supprime" : false,
"networkType" : "SCHOLAR"
},
"external_ref" : null,
"distanceBetweenPreviousStopCalculated" : 0.0,
"distanceBetweenPreviousStopReal" : null
} ]
'''
STOPS = '''
[ {
"id" : 3281,
"stop_point_id" : 827,
"name" : "Les Loges de Dressais",
"latitude" : 46.7317874000000018,
"longitude" : 1.7887462999999999,
"bearing" : 0.0,
"position" : 2,
"commercial_stop_area" : 3281,
"commercial_name" : "Les Loges de Dressais",
"liaisons" : [ ],
"registrationNumber" : null
}, {
"id" : 3279,
"stop_point_id" : 828,
"name" : "La Cueille",
"latitude" : 46.7500219000000001,
"longitude" : 1.7890467000000001,
"bearing" : 0.0,
"position" : 3,
"commercial_stop_area" : 3279,
"commercial_name" : "La Cueille",
"liaisons" : [ ],
"registrationNumber" : null
}, {
"id" : 3560,
"stop_point_id" : 869,
"name" : "Ecole Primaire SAINT-VINCENT",
"latitude" : 46.7423843999999988,
"longitude" : 1.83196010000000009,
"bearing" : 0.0,
"position" : 3,
"commercial_stop_area" : 3560,
"commercial_name" : "Ecole Primaire SAINT-VINCENT",
"liaisons" : [ ],
"registrationNumber" : null
} ]
'''
# https://iti.okina.fr/api/Okina/REST/b2b/ods
ODS = '''[ {
"id" : {
"institutionId" : 276,
"sequenceNumber" : 1
},
"institution" : {
"id" : 276,
"schoolEstablishmentUai" : "0360155Y",
"okinaStopAreas" : null
},
"originDestinationSequenceElements" : [ {
"id" : 6,
"okinaVehicleJourney" : {
"detached" : false,
"objectId" : "Europe Voyages 23:VehicleJourney:84",
"objectVersion" : 1,
"creationTime" : 1491516000000,
"creatorId" : null,
"saved" : false,
"id" : 84,
"comment" : null,
"transportMode" : null,
"publishedJourneyName" : "SYNDICAT ARDENTES 4 (semaine Aller)",
"publishedJourneyIdentifier" : "SYNDICAT ARDENTES 4 (semaine Aller)",
"facility" : null,
"vehicleTypeIdentifier" : null,
"number" : 84,
"mobilityRestrictedSuitability" : null,
"flexibleService" : null,
"route" : null,
"journeyPattern" : null,
"company" : null,
"footnotes" : null,
"timetables" : null,
"vehicleJourneyAtStops" : null,
"journeyCategory" : "Timesheet",
"journeyFrequencies" : null,
"okinaJourneyPattern" : null,
"okinaRoute" : null,
"etat" : 0,
"supprime" : false,
"okinaVehicleJourneyAtStops" : null,
"counterGroups" : null,
"registrationNumber" : null,
"filled" : false
},
"okinaJourneyPattern" : null,
"position" : 1,
"originDestination" : {
"institutionId" : 276,
"sequenceNumber" : 1
}
} ],
"oppositeOds" : null,
"way" : "WAY_TO"
}, {
"id" : {
"institutionId" : 276,
"sequenceNumber" : 2
},
"institution" : {
"id" : 276,
"schoolEstablishmentUai" : "0360155Y",
"okinaStopAreas" : null
},
"originDestinationSequenceElements" : [ {
"id" : 203,
"okinaVehicleJourney" : {
"detached" : false,
"objectId" : "STI CENTRE:VehicleJourney:90",
"objectVersion" : 1,
"creationTime" : 1491516000000,
"creatorId" : null,
"saved" : false,
"id" : 90,
"comment" : null,
"transportMode" : null,
"publishedJourneyName" : "SYNDICAT ARDENTES 6 (semaine Aller)",
"publishedJourneyIdentifier" : "SYNDICAT ARDENTES 6 (semaine Aller)",
"facility" : null,
"vehicleTypeIdentifier" : null,
"number" : 90,
"mobilityRestrictedSuitability" : null,
"flexibleService" : null,
"route" : null,
"journeyPattern" : null,
"company" : null,
"footnotes" : null,
"timetables" : null,
"vehicleJourneyAtStops" : null,
"journeyCategory" : "Timesheet",
"journeyFrequencies" : null,
"okinaJourneyPattern" : null,
"okinaRoute" : null,
"etat" : 0,
"supprime" : false,
"okinaVehicleJourneyAtStops" : null,
"counterGroups" : null,
"registrationNumber" : null,
"filled" : false
},
"okinaJourneyPattern" : null,
"position" : 1,
"originDestination" : {
"institutionId" : 276,
"sequenceNumber" : 2
}
} ],
"oppositeOds" : null,
"way" : "WAY_TO"
} ]
'''
# https://iti.okina.fr/api/Okina/REST/b2b/ods/institution/276/stop-area/3282
ODS_LINES = '''[ [ { "id" : 24, "name" : "LIGNE 24" } ],
[ { "id": 22,"name": "LIGNE 22" } ],
[ { "id": 24, "name" : "LIGNE 24" }, { "id": 23, "name": "LIGNE 23" } ] ]
'''
# https://iti.okina.fr/api/Okina/REST/b2b/ods/institution/276/subscriberCity/36005
# https://iti.okina.fr/api/Okina/REST/b2b/ods/subscriberCity/36005
ODS_FULL = '''[ {
"id" : {
"institutionId" : 276,
"sequenceNumber" : 1
},
"institution" : {
"id" : 276,
"schoolEstablishmentUai" : "0360155Y",
"okinaStopAreas" : null
},
"originDestinationSequenceElements" : [ {
"id" : 6,
"okinaVehicleJourney" : {
"detached" : false,
"objectId" : "Europe Voyages 23:VehicleJourney:84",
"objectVersion" : 1,
"creationTime" : 1491516000000,
"creatorId" : null,
"saved" : false,
"id" : 84,
"comment" : null,
"transportMode" : null,
"publishedJourneyName" : "SYNDICAT ARDENTES 4 (semaine Aller)",
"publishedJourneyIdentifier" : "SYNDICAT ARDENTES 4 (semaine Aller)",
"facility" : null,
"vehicleTypeIdentifier" : null,
"number" : 84,
"mobilityRestrictedSuitability" : null,
"flexibleService" : null,
"route" : null,
"journeyPattern" : null,
"company" : null,
"footnotes" : null,
"timetables" : null,
"vehicleJourneyAtStops" : null,
"journeyCategory" : "Timesheet",
"journeyFrequencies" : null,
"okinaJourneyPattern" : {
"detached" : false,
"objectId" : "europevoyages:JourneyPattern:86",
"objectVersion" : 1,
"creationTime" : 1491516000000,
"creatorId" : null,
"saved" : false,
"id" : 86,
"name" : "Brenne 1 vers écoles Antoine Fée, Saint Martin et Saint Vincent (semaine Aller)",
"comment" : null,
"registrationNumber" : null,
"publishedName" : "Brenne 1 vers écoles Antoine Fée, Saint Martin et Saint Vincent",
"sectionStatus" : "Todo",
"route" : null,
"departureStopPoint" : null,
"arrivalStopPoint" : null,
"stopPoints" : null,
"vehicleJourneys" : null,
"routeSections" : null,
"okinaStopPoints" : [ {
"id" : 825,
"detached" : false,
"objectId" : "chateauroux:StopPoint:825",
"objectVersion" : 1,
"creationTime" : 1491551801241,
"creatorId" : null,
"saved" : false,
"position" : 0,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : {
"detached" : false,
"objectId" : "chateauroux:StopArea:Boarding_36005_004",
"objectVersion" : 1,
"creationTime" : null,
"creatorId" : null,
"saved" : false,
"longitude" : 1.81673930000000006,
"latitude" : 46.719458699999997,
"longLatType" : null,
"x" : null,
"y" : null,
"projectionType" : null,
"countryCode" : "36005",
"zipCode" : "36120",
"cityName" : "Ardentes",
"streetName" : null,
"id" : 3273,
"name" : "Brenne 1",
"comment" : null,
"areaType" : "BoardingPosition",
"registrationNumber" : "36005_004",
"nearestTopicName" : null,
"url" : null,
"timeZone" : null,
"fareCode" : null,
"liftAvailable" : null,
"mobilityRestrictedSuitable" : null,
"stairsAvailable" : null,
"intUserNeeds" : null,
"parent" : null,
"routingConstraintLines" : null,
"routingConstraintAreas" : null,
"containedStopAreas" : null,
"containedStopPoints" : null,
"accessLinks" : null,
"routeSectionDepartures" : null,
"routeSectionArrivals" : null,
"connectionStartLinks" : null,
"connectionEndLinks" : null,
"accessPoints" : null,
"okinaContainedStopPoints" : null,
"okinaParent" : null,
"bearing" : 0.0,
"cityCode" : "36005",
"okinaContainedStopAreas" : null,
"userNeeds" : [ ],
"filled" : false
},
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 826,
"detached" : false,
"objectId" : "chateauroux:StopPoint:826",
"objectVersion" : 1,
"creationTime" : 1491551801241,
"creatorId" : null,
"saved" : false,
"position" : 1,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : {
"detached" : false,
"objectId" : "chateauroux:StopArea:Boarding_36005_005",
"objectVersion" : 1,
"creationTime" : null,
"creatorId" : null,
"saved" : false,
"longitude" : 1.80696429999999997,
"latitude" : 46.7233643000000001,
"longLatType" : null,
"x" : null,
"y" : null,
"projectionType" : null,
"countryCode" : "36005",
"zipCode" : "36120",
"cityName" : "Ardentes",
"streetName" : null,
"id" : 3274,
"name" : "Brenne 2",
"comment" : null,
"areaType" : "BoardingPosition",
"registrationNumber" : "36005_005",
"nearestTopicName" : null,
"url" : null,
"timeZone" : null,
"fareCode" : null,
"liftAvailable" : null,
"mobilityRestrictedSuitable" : null,
"stairsAvailable" : null,
"intUserNeeds" : null,
"parent" : null,
"routingConstraintLines" : null,
"routingConstraintAreas" : null,
"containedStopAreas" : null,
"containedStopPoints" : null,
"accessLinks" : null,
"routeSectionDepartures" : null,
"routeSectionArrivals" : null,
"connectionStartLinks" : null,
"connectionEndLinks" : null,
"accessPoints" : null,
"okinaContainedStopPoints" : null,
"okinaParent" : null,
"bearing" : 0.0,
"cityCode" : "36005",
"okinaContainedStopAreas" : null,
"userNeeds" : [ ],
"filled" : false
},
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 827,
"detached" : false,
"objectId" : "chateauroux:StopPoint:827",
"objectVersion" : 1,
"creationTime" : 1491551801242,
"creatorId" : null,
"saved" : false,
"position" : 2,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : {
"detached" : false,
"objectId" : "chateauroux:StopArea:Boarding_36005_012",
"objectVersion" : 1,
"creationTime" : null,
"creatorId" : null,
"saved" : false,
"longitude" : 1.7887462999999999,
"latitude" : 46.7317874000000018,
"longLatType" : null,
"x" : null,
"y" : null,
"projectionType" : null,
"countryCode" : "36005",
"zipCode" : "36120",
"cityName" : "Ardentes",
"streetName" : null,
"id" : 3281,
"name" : "Les Loges de Dressais",
"comment" : null,
"areaType" : "BoardingPosition",
"registrationNumber" : "36005_012",
"nearestTopicName" : null,
"url" : null,
"timeZone" : null,
"fareCode" : null,
"liftAvailable" : null,
"mobilityRestrictedSuitable" : null,
"stairsAvailable" : null,
"intUserNeeds" : null,
"parent" : null,
"routingConstraintLines" : null,
"routingConstraintAreas" : null,
"containedStopAreas" : null,
"containedStopPoints" : null,
"accessLinks" : null,
"routeSectionDepartures" : null,
"routeSectionArrivals" : null,
"connectionStartLinks" : null,
"connectionEndLinks" : null,
"accessPoints" : null,
"okinaContainedStopPoints" : null,
"okinaParent" : null,
"bearing" : 0.0,
"cityCode" : "36005",
"okinaContainedStopAreas" : null,
"userNeeds" : [ ],
"filled" : false
},
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 828,
"detached" : false,
"objectId" : "chateauroux:StopPoint:828",
"objectVersion" : 1,
"creationTime" : 1491551801242,
"creatorId" : null,
"saved" : false,
"position" : 3,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : {
"detached" : false,
"objectId" : "chateauroux:StopArea:Boarding_36005_010",
"objectVersion" : 1,
"creationTime" : null,
"creatorId" : null,
"saved" : false,
"longitude" : 1.7890467000000001,
"latitude" : 46.7500219000000001,
"longLatType" : null,
"x" : null,
"y" : null,
"projectionType" : null,
"countryCode" : "36005",
"zipCode" : "36120",
"cityName" : "Ardentes",
"streetName" : null,
"id" : 3279,
"name" : "La Cueille",
"comment" : null,
"areaType" : "BoardingPosition",
"registrationNumber" : "36005_010",
"nearestTopicName" : null,
"url" : null,
"timeZone" : null,
"fareCode" : null,
"liftAvailable" : null,
"mobilityRestrictedSuitable" : null,
"stairsAvailable" : null,
"intUserNeeds" : null,
"parent" : null,
"routingConstraintLines" : null,
"routingConstraintAreas" : null,
"containedStopAreas" : null,
"containedStopPoints" : null,
"accessLinks" : null,
"routeSectionDepartures" : null,
"routeSectionArrivals" : null,
"connectionStartLinks" : null,
"connectionEndLinks" : null,
"accessPoints" : null,
"okinaContainedStopPoints" : null,
"okinaParent" : null,
"bearing" : 0.0,
"cityCode" : "36005",
"okinaContainedStopAreas" : null,
"userNeeds" : [ ],
"filled" : false
},
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 829,
"detached" : false,
"objectId" : "chateauroux:StopPoint:829",
"objectVersion" : 1,
"creationTime" : 1491551801242,
"creatorId" : null,
"saved" : false,
"position" : 4,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : {
"detached" : false,
"objectId" : "chateauroux:StopArea:Boarding_36005_013",
"objectVersion" : 1,
"creationTime" : null,
"creatorId" : null,
"saved" : false,
"longitude" : 1.79444730000000008,
"latitude" : 46.7477992999999969,
"longLatType" : null,
"x" : null,
"y" : null,
"projectionType" : null,
"countryCode" : "36005",
"zipCode" : "36120",
"cityName" : "Ardentes",
"streetName" : null,
"id" : 3282,
"name" : "Les Loges du Plessis",
"comment" : null,
"areaType" : "BoardingPosition",
"registrationNumber" : "36005_013",
"nearestTopicName" : null,
"url" : null,
"timeZone" : null,
"fareCode" : null,
"liftAvailable" : null,
"mobilityRestrictedSuitable" : null,
"stairsAvailable" : null,
"intUserNeeds" : null,
"parent" : null,
"routingConstraintLines" : null,
"routingConstraintAreas" : null,
"containedStopAreas" : null,
"containedStopPoints" : null,
"accessLinks" : null,
"routeSectionDepartures" : null,
"routeSectionArrivals" : null,
"connectionStartLinks" : null,
"connectionEndLinks" : null,
"accessPoints" : null,
"okinaContainedStopPoints" : null,
"okinaParent" : null,
"bearing" : 0.0,
"cityCode" : "36005",
"okinaContainedStopAreas" : null,
"userNeeds" : [ ],
"filled" : false
},
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 830,
"detached" : false,
"objectId" : "chateauroux:StopPoint:830",
"objectVersion" : 1,
"creationTime" : 1491551801243,
"creatorId" : null,
"saved" : false,
"position" : 5,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 831,
"detached" : false,
"objectId" : "chateauroux:StopPoint:831",
"objectVersion" : 1,
"creationTime" : 1491551801243,
"creatorId" : null,
"saved" : false,
"position" : 6,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 832,
"detached" : false,
"objectId" : "chateauroux:StopPoint:832",
"objectVersion" : 1,
"creationTime" : 1491551801244,
"creatorId" : null,
"saved" : false,
"position" : 7,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
} ],
"okinaVehicleJourneys" : null,
"etat" : 0,
"supprime" : false,
"okinaRoute" : null,
"okinaDepartureStopPoint" : null,
"okinaArrivalStopPoint" : null,
"filled" : false
},
"okinaRoute" : null,
"etat" : 0,
"supprime" : false,
"okinaVehicleJourneyAtStops" : null,
"counterGroups" : null,
"registrationNumber" : null,
"filled" : false
},
"okinaJourneyPattern" : null,
"position" : 1,
"originDestination" : {
"institutionId" : 276,
"sequenceNumber" : 1
}
} ],
"oppositeOds" : [ {
"id" : {
"institutionId" : 276,
"sequenceNumber" : 3
},
"institution" : {
"id" : 276,
"schoolEstablishmentUai" : "0360155Y",
"okinaStopAreas" : null
},
"originDestinationSequenceElements" : [ {
"id" : 3,
"okinaVehicleJourney" : {
"detached" : false,
"objectId" : "Europe Voyages 23:VehicleJourney:86",
"objectVersion" : 1,
"creationTime" : 1491516000000,
"creatorId" : null,
"saved" : false,
"id" : 86,
"comment" : null,
"transportMode" : null,
"publishedJourneyName" : "SYNDICAT ARDENTES 4 (mercredi Retour)",
"publishedJourneyIdentifier" : "SYNDICAT ARDENTES 4 (mercredi Retour)",
"facility" : null,
"vehicleTypeIdentifier" : null,
"number" : 86,
"mobilityRestrictedSuitability" : null,
"flexibleService" : null,
"route" : null,
"journeyPattern" : null,
"company" : null,
"footnotes" : null,
"timetables" : null,
"vehicleJourneyAtStops" : null,
"journeyCategory" : "Timesheet",
"journeyFrequencies" : null,
"okinaJourneyPattern" : {
"detached" : false,
"objectId" : "europevoyages:JourneyPattern:89",
"objectVersion" : 1,
"creationTime" : 1491516000000,
"creatorId" : null,
"saved" : false,
"id" : 89,
"name" : "écoles St Vincent, Antoine Fée et St Martin vers Brenne 1 (mercredi Retour) 2017-04-07 10:10:43.949",
"comment" : null,
"registrationNumber" : null,
"publishedName" : "écoles St Vincent, Antoine Fée et St Martin vers Brenne 1 2017-04-07 10:10:43.949",
"sectionStatus" : "Todo",
"route" : null,
"departureStopPoint" : null,
"arrivalStopPoint" : null,
"stopPoints" : null,
"vehicleJourneys" : null,
"routeSections" : null,
"okinaStopPoints" : [ {
"id" : 849,
"detached" : false,
"objectId" : "chateauroux:StopPoint:849",
"objectVersion" : 1,
"creationTime" : 1491552643953,
"creatorId" : null,
"saved" : false,
"position" : 0,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 850,
"detached" : false,
"objectId" : "chateauroux:StopPoint:850",
"objectVersion" : 1,
"creationTime" : 1491552643953,
"creatorId" : null,
"saved" : false,
"position" : 1,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 851,
"detached" : false,
"objectId" : "chateauroux:StopPoint:851",
"objectVersion" : 1,
"creationTime" : 1491552643954,
"creatorId" : null,
"saved" : false,
"position" : 2,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 852,
"detached" : false,
"objectId" : "chateauroux:StopPoint:852",
"objectVersion" : 1,
"creationTime" : 1491552643954,
"creatorId" : null,
"saved" : false,
"position" : 3,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 853,
"detached" : false,
"objectId" : "chateauroux:StopPoint:853",
"objectVersion" : 1,
"creationTime" : 1491552643954,
"creatorId" : null,
"saved" : false,
"position" : 4,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 854,
"detached" : false,
"objectId" : "chateauroux:StopPoint:854",
"objectVersion" : 1,
"creationTime" : 1491552643954,
"creatorId" : null,
"saved" : false,
"position" : 5,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 855,
"detached" : false,
"objectId" : "chateauroux:StopPoint:855",
"objectVersion" : 1,
"creationTime" : 1491552643954,
"creatorId" : null,
"saved" : false,
"position" : 6,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 856,
"detached" : false,
"objectId" : "chateauroux:StopPoint:856",
"objectVersion" : 1,
"creationTime" : 1491552643954,
"creatorId" : null,
"saved" : false,
"position" : 7,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
} ],
"okinaVehicleJourneys" : null,
"etat" : 1,
"supprime" : true,
"okinaRoute" : null,
"okinaDepartureStopPoint" : null,
"okinaArrivalStopPoint" : null,
"filled" : false
},
"okinaRoute" : null,
"etat" : 1,
"supprime" : false,
"okinaVehicleJourneyAtStops" : null,
"counterGroups" : null,
"registrationNumber" : null,
"filled" : false
},
"okinaJourneyPattern" : null,
"position" : 1,
"originDestination" : {
"institutionId" : 276,
"sequenceNumber" : 3
}
} ],
"oppositeOds" : [ {
"institutionId" : 276,
"sequenceNumber" : 1
} ],
"way" : "WAY_BACK"
}, {
"id" : {
"institutionId" : 276,
"sequenceNumber" : 4
},
"institution" : {
"id" : 276,
"schoolEstablishmentUai" : "0360155Y",
"okinaStopAreas" : null
},
"originDestinationSequenceElements" : [ {
"id" : 4,
"okinaVehicleJourney" : {
"detached" : false,
"objectId" : "Europe Voyages 23:VehicleJourney:85",
"objectVersion" : 1,
"creationTime" : 1491516000000,
"creatorId" : null,
"saved" : false,
"id" : 85,
"comment" : null,
"transportMode" : null,
"publishedJourneyName" : "SYNDICAT ARDENTES 4 (semaine Retour)",
"publishedJourneyIdentifier" : "SYNDICAT ARDENTES 4 (semaine Retour)",
"facility" : null,
"vehicleTypeIdentifier" : null,
"number" : 85,
"mobilityRestrictedSuitability" : null,
"flexibleService" : null,
"route" : null,
"journeyPattern" : null,
"company" : null,
"footnotes" : null,
"timetables" : null,
"vehicleJourneyAtStops" : null,
"journeyCategory" : "Timesheet",
"journeyFrequencies" : null,
"okinaJourneyPattern" : {
"detached" : false,
"objectId" : "europevoyages:JourneyPattern:87",
"objectVersion" : 1,
"creationTime" : 1491516000000,
"creatorId" : null,
"saved" : false,
"id" : 87,
"name" : "écoles St Vincent, Antoine Fée et St Martin vers Brenne 1 (semaine Retour)",
"comment" : null,
"registrationNumber" : null,
"publishedName" : "écoles St Vincent, Antoine Fée et St Martin vers Brenne 1",
"sectionStatus" : "Todo",
"route" : null,
"departureStopPoint" : null,
"arrivalStopPoint" : null,
"stopPoints" : null,
"vehicleJourneys" : null,
"routeSections" : null,
"okinaStopPoints" : [ {
"id" : 833,
"detached" : false,
"objectId" : "chateauroux:StopPoint:833",
"objectVersion" : 1,
"creationTime" : 1491552070527,
"creatorId" : null,
"saved" : false,
"position" : 0,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 834,
"detached" : false,
"objectId" : "chateauroux:StopPoint:834",
"objectVersion" : 1,
"creationTime" : 1491552070528,
"creatorId" : null,
"saved" : false,
"position" : 1,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 835,
"detached" : false,
"objectId" : "chateauroux:StopPoint:835",
"objectVersion" : 1,
"creationTime" : 1491552070528,
"creatorId" : null,
"saved" : false,
"position" : 2,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 836,
"detached" : false,
"objectId" : "chateauroux:StopPoint:836",
"objectVersion" : 1,
"creationTime" : 1491552070529,
"creatorId" : null,
"saved" : false,
"position" : 3,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 837,
"detached" : false,
"objectId" : "chateauroux:StopPoint:837",
"objectVersion" : 1,
"creationTime" : 1491552070529,
"creatorId" : null,
"saved" : false,
"position" : 4,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 838,
"detached" : false,
"objectId" : "chateauroux:StopPoint:838",
"objectVersion" : 1,
"creationTime" : 1491552070530,
"creatorId" : null,
"saved" : false,
"position" : 5,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 839,
"detached" : false,
"objectId" : "chateauroux:StopPoint:839",
"objectVersion" : 1,
"creationTime" : 1491552070530,
"creatorId" : null,
"saved" : false,
"position" : 6,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
}, {
"id" : 840,
"detached" : false,
"objectId" : "chateauroux:StopPoint:840",
"objectVersion" : 1,
"creationTime" : 1491552070530,
"creatorId" : null,
"saved" : false,
"position" : 7,
"forBoarding" : null,
"forAlighting" : null,
"containedInStopArea" : null,
"route" : null,
"comment" : null,
"okinaRoute" : null,
"okinaContainedInStopArea" : null,
"journeyPatternsDestination" : null,
"journeyPatternsOrigin" : null,
"okinaJourneyPatterns" : null,
"vehicleJourneyAtStops" : null,
"registrationNumber" : null,
"filled" : false
} ],
"okinaVehicleJourneys" : null,
"etat" : 0,
"supprime" : true,
"okinaRoute" : null,
"okinaDepartureStopPoint" : null,
"okinaArrivalStopPoint" : null,
"filled" : false
},
"okinaRoute" : null,
"etat" : 0,
"supprime" : false,
"okinaVehicleJourneyAtStops" : null,
"counterGroups" : null,
"registrationNumber" : null,
"filled" : false
},
"okinaJourneyPattern" : null,
"position" : 1,
"originDestination" : {
"institutionId" : 276,
"sequenceNumber" : 4
}
} ],
"oppositeOds" : [ {
"institutionId" : 276,
"sequenceNumber" : 1
} ],
"way" : "WAY_BACK"
} ],
"way" : "WAY_TO"
} ]
'''
# https://iti.okina.fr/api/Okina/REST/b2b/topology/lines
LINES = '''[ {
"id" : 45,
"name" : "019 - 02 - VELLES LYCEES DE CHATEAUROUX"
}, {
"id" : 3,
"name" : "ARTHON COLLEGE 1"
}, {
"id" : 4,
"name" : "ARTHON COLLEGE 2"
} ]
'''
# https://iti.okina.fr/api/Okina/REST/b2b/topology/networks
NETWORKS = '''[ {
"id" : 2,
"name" : "réseau scolaire"
} ]
'''
# https://iti.okina.fr/api/Okina/REST/b2b/topology/vehicle-journeys
VEHICLE_JOURNEYS = '''[ {
"id" : 306,
"name" : "019 02 - VELLES LYCEES DE CHATEAUROUX"
}, {
"id" : 307,
"name" : "019-02 - VELLES LYCEES DE CHATEAUROUX"
}, {
"id" : 305,
"name" : "019-02 - VELLES LYCEES DE CHATEAUROUX"
} ]
'''
QRCODE_400 = '''{
"code" : 3,
"status" : 400,
"message" : "Subscriber with ID 123 has no passcard number to generate qr code from."
}'''
QRCODE_404 = '''{
"code" : 1,
"status" : 404,
"message" : "Subscriber with ID 123 not found."
}'''
@pytest.fixture
def okina(db):
return Okina.objects.create(
slug='test', service_url='https://okina.example.net/b2b/', username='usertest', password='userpass'
)
def test_okina_cities(app, okina):
endpoint = tests.utils.generic_endpoint_url('okina', 'cities', slug=okina.slug)
assert endpoint == '/okina/test/cities'
with mock.patch('passerelle.utils.Request.get') as requests_get:
requests_get.return_value = tests.utils.FakedResponse(content=CITIES, status_code=200)
resp = app.get(endpoint, status=200)
assert requests_get.call_count == 1
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/cities'
assert requests_get.call_args[1]['auth'] == ('usertest', 'userpass')
assert 'data' in resp.json
assert resp.json['err'] == 0
assert len(resp.json['data']) == 2
assert resp.json['data'][0]['id'] == '83355'
assert resp.json['data'][0]['insee'] == '36005'
assert resp.json['data'][0]['text'] == 'ARDENTES (36120)'
assert resp.json['data'][0]['lat'] is None
requests_get.return_value = tests.utils.FakedResponse(content=CITIES_NEW, status_code=200)
resp = app.get(endpoint, status=200)
assert requests_get.call_count == 2
assert 'data' in resp.json
assert resp.json['err'] == 0
assert len(resp.json['data']) == 1
assert resp.json['data'][0]['id'] == '83355'
assert resp.json['data'][0]['insee'] == '36005'
assert resp.json['data'][0]['text'] == 'ARDENTES (36120)'
assert resp.json['data'][0]['lat'] is None
def test_okina_classes(app, okina):
endpoint = tests.utils.generic_endpoint_url('okina', 'classes', slug=okina.slug)
assert endpoint == '/okina/test/classes'
with mock.patch('passerelle.utils.Request.get') as requests_get:
requests_get.return_value = tests.utils.FakedResponse(content=CLASSES, status_code=200)
resp = app.get(endpoint, status=200)
assert requests_get.call_count == 1
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/classes'
assert resp.json['err'] == 0
assert len(resp.json['data']) == 4
assert resp.json['data'][0]['id'] == '1'
assert resp.json['data'][0]['text'] == 'École maternelle - Petite section'
def test_okina_institutions(app, okina):
endpoint = tests.utils.generic_endpoint_url('okina', 'institutions', slug=okina.slug)
assert endpoint == '/okina/test/institutions'
with mock.patch('passerelle.utils.Request.get') as requests_get:
for content in (INSTITUTIONS, INSTITUTIONS_NEW):
requests_get.return_value = tests.utils.FakedResponse(content=content, status_code=200)
resp = app.get(endpoint, status=200)
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/institutions'
assert resp.json['err'] == 0
assert len(resp.json['data']) == 2
assert resp.json['data'][0]['id'] == '277'
assert resp.json['data'][0]['text'] == 'Collège Touvent'
assert resp.json['data'][0]['lat'] == '46.791332586468016'
assert resp.json['data'][0]['lon'] == '1.6926355997775921'
resp = app.get(endpoint, params={'insee': '36005'}, status=200)
assert (
requests_get.call_args[0][0] == 'https://okina.example.net/b2b/institutions?inseeCode=36005'
)
assert resp.json['err'] == 0
assert len(resp.json['data']) == 2
assert resp.json['data'][0]['id'] == '277'
assert resp.json['data'][0]['text'] == 'Collège Touvent'
resp = app.get(endpoint + '/from-city/36005/', status=200)
assert (
requests_get.call_args[0][0]
== 'https://okina.example.net/b2b/institutions/subscriberCity/36005'
)
assert resp.json['err'] == 0
assert len(resp.json['data']) == 2
assert resp.json['data'][0]['id'] == '277'
assert resp.json['data'][0]['text'] == 'Collège Touvent'
def test_okina_search(app, okina):
endpoint = tests.utils.generic_endpoint_url('okina', 'search', slug=okina.slug)
assert endpoint == '/okina/test/search'
with mock.patch('passerelle.utils.Request.post') as requests_post:
requests_post.return_value = tests.utils.FakedResponse(content=SEARCH, status_code=200)
# refuse anonymous access
resp = app.get(endpoint + '?lat=46.828652&lon=1.701463&institution=277', status=403)
apiuser = ApiUser.objects.create(username='all', keytype='', key='')
obj_type = ContentType.objects.get_for_model(okina)
AccessRight.objects.create(
codename='can_access', apiuser=apiuser, resource_type=obj_type, resource_pk=okina.pk
)
app.get(endpoint + '?lat=46.828652', status=400) # missing argument
resp = app.get(endpoint + '?lat=46.828652&lon=1.701463&institution=277', status=200)
assert requests_post.call_args[0][0] == 'https://okina.example.net/b2b/wishes/search'
assert json.loads(requests_post.call_args[1]['data']) == {
'type': 'CLOSE_SCHOLAR',
'from-address': '',
'from-lat': '46.828652',
'from-long': '1.701463',
'institution-id': '277',
}
assert resp.json['err'] == 0
assert len(resp.json['data']) == 2
assert resp.json['data'][0]['id'] == '3312'
assert resp.json['data'][0]['text'] == 'Le Grand Verger'
assert resp.json['data'][0]['lat'] == 46.8444186
assert resp.json['data'][0]['lon'] == 1.708197
# french decimals
resp = app.get(
endpoint + '?lat=46,8&lon=1,71&address=nowhere&mode=FAR_ALL&institution=280', status=200
)
assert requests_post.call_args[0][0] == 'https://okina.example.net/b2b/wishes/search'
assert json.loads(requests_post.call_args[1]['data']) == {
'type': 'FAR_ALL',
'from-address': 'nowhere',
'from-lat': '46.8',
'from-long': '1.71',
'institution-id': '280',
}
assert resp.json['err'] == 0
def test_okina_stops_area(app, okina):
endpoint = tests.utils.generic_endpoint_url('okina', 'stop-areas', slug=okina.slug)
assert endpoint == '/okina/test/stop-areas'
with mock.patch('passerelle.utils.Request.get') as requests_get:
requests_get.return_value = tests.utils.FakedResponse(content=STOPS, status_code=200)
resp = app.get(endpoint + '/from-city/36005/to-institution/276/', status=200)
assert (
requests_get.call_args[0][0]
== 'https://okina.example.net/b2b/stop-areas/subscriberCity/36005/institution/276'
)
assert resp.json['err'] == 0
assert len(resp.json['data']) == 3
assert resp.json['data'][0]['id'] == '3281'
assert resp.json['data'][0]['text'] == 'Les Loges de Dressais'
def test_okina_ods(app, okina):
endpoint = tests.utils.generic_endpoint_url('okina', 'origin-destinations', slug=okina.slug)
assert endpoint == '/okina/test/origin-destinations'
with mock.patch('passerelle.utils.Request.get') as requests_get:
requests_get.return_value = tests.utils.FakedResponse(content=ODS, status_code=200)
resp = app.get(endpoint, status=200)
assert requests_get.call_count == 1
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/ods'
assert resp.json['err'] == 0
assert len(resp.json['data']) == 2
assert resp.json['data'][0]['id'] == 'inst:276-seq:1-6-84'
assert resp.json['data'][0]['text'] == 'SYNDICAT ARDENTES 4 (semaine Aller)'
assert resp.json['data'][0]['identifier'] == 'SYNDICAT ARDENTES 4 (semaine Aller)'
assert resp.json['data'][0]['vehicle_journey_id'] == '84'
requests_get.return_value = tests.utils.FakedResponse(content=ODS, status_code=200)
resp = app.get(endpoint + '/to-institution/276/', status=200)
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/ods/institution/276'
assert resp.json['err'] == 0
assert len(resp.json['data']) == 2
assert resp.json['data'][0]['id'] == 'inst:276-seq:1-6-84'
assert resp.json['data'][0]['text'] == 'SYNDICAT ARDENTES 4 (semaine Aller)'
assert resp.json['data'][0]['identifier'] == 'SYNDICAT ARDENTES 4 (semaine Aller)'
assert resp.json['data'][0]['vehicle_journey_id'] == '84'
requests_get.return_value = tests.utils.FakedResponse(content=ODS_LINES, status_code=200)
resp = app.get(endpoint + '/from-stop-area/3282/to-institution/276/', status=200)
assert (
requests_get.call_args[0][0] == 'https://okina.example.net/b2b/ods/institution/276/stop-area/3282'
)
assert resp.json['err'] == 0
assert len(resp.json['data']) == 3
assert resp.json['data'][0]['id'] == '1'
assert resp.json['data'][0]['text'] == 'LIGNE 24'
assert len(resp.json['data'][0]['lines']) == 1
assert resp.json['data'][0]['lines'][0]['id'] == '24'
assert resp.json['data'][0]['lines'][0]['text'] == 'LIGNE 24'
assert resp.json['data'][1]['id'] == '2'
assert resp.json['data'][1]['text'] == 'LIGNE 22'
assert len(resp.json['data'][1]['lines']) == 1
assert resp.json['data'][1]['lines'][0]['id'] == '22'
assert resp.json['data'][1]['lines'][0]['text'] == 'LIGNE 22'
assert resp.json['data'][2]['id'] == '3'
assert resp.json['data'][2]['text'] == 'LIGNE 24 + LIGNE 23'
assert len(resp.json['data'][2]['lines']) == 2
assert resp.json['data'][2]['lines'][0]['id'] == '24'
assert resp.json['data'][2]['lines'][0]['text'] == 'LIGNE 24'
assert resp.json['data'][2]['lines'][1]['id'] == '23'
assert resp.json['data'][2]['lines'][1]['text'] == 'LIGNE 23'
requests_get.return_value = tests.utils.FakedResponse(content=ODS_FULL, status_code=200)
resp = app.get(endpoint + '/from-city/36005/to-institution/276/', status=200)
assert (
requests_get.call_args[0][0]
== 'https://okina.example.net/b2b/ods/institution/276/subscriberCity/36005'
)
assert resp.json['err'] == 0
assert len(resp.json['data']) == 1
assert resp.json['data'][0]['id'] == 'inst:276-seq:1-6-84'
assert (
resp.json['data'][0]['text'] == 'Brenne 1 vers écoles Antoine Fée, Saint Martin et Saint Vincent'
)
assert resp.json['data'][0]['identifier'] == 'SYNDICAT ARDENTES 4 (semaine Aller)'
assert resp.json['data'][0]['vehicle_journey_id'] == '84'
requests_get.return_value = tests.utils.FakedResponse(content=ODS_FULL, status_code=200)
resp = app.get(endpoint + '/from-city/36005/', status=200)
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/ods/subscriberCity/36005'
assert resp.json['err'] == 0
assert len(resp.json['data']) == 1
assert resp.json['data'][0]['id'] == 'inst:276-seq:1-6-84'
assert (
resp.json['data'][0]['text'] == 'Brenne 1 vers écoles Antoine Fée, Saint Martin et Saint Vincent'
)
assert resp.json['data'][0]['identifier'] == 'SYNDICAT ARDENTES 4 (semaine Aller)'
assert resp.json['data'][0]['vehicle_journey_id'] == '84'
def test_okina_topology(app, okina):
endpoint = tests.utils.generic_endpoint_url('okina', 'topology', slug=okina.slug)
assert endpoint == '/okina/test/topology'
with mock.patch('passerelle.utils.Request.get') as requests_get:
requests_get.return_value = tests.utils.FakedResponse(content=LINES, status_code=200)
resp = app.get(endpoint + '/lines/', status=200)
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/topology/lines'
assert resp.json['err'] == 0
assert len(resp.json['data']) == 3
assert resp.json['data'][0]['id'] == '45'
assert resp.json['data'][0]['text'] == '019 - 02 - VELLES LYCEES DE CHATEAUROUX'
requests_get.return_value = tests.utils.FakedResponse(content=NETWORKS, status_code=200)
resp = app.get(endpoint + '/networks/', status=200)
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/topology/networks'
assert resp.json['err'] == 0
assert len(resp.json['data']) == 1
assert resp.json['data'][0]['id'] == '2'
assert resp.json['data'][0]['text'] == 'réseau scolaire'
requests_get.return_value = tests.utils.FakedResponse(content=VEHICLE_JOURNEYS, status_code=200)
resp = app.get(endpoint + '/vehicle-journeys/', status=200)
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/topology/vehicle-journeys'
assert resp.json['err'] == 0
assert len(resp.json['data']) == 3
assert resp.json['data'][0]['id'] == '306'
assert resp.json['data'][0]['text'] == '019 02 - VELLES LYCEES DE CHATEAUROUX'
def test_okina_errors(app, okina):
with mock.patch('passerelle.utils.Request.get') as requests_get:
for response in (
(200, '{"foo": "bar"}'), # not a list
(200, '{["foo": "bar"]}'), # list of malformatted dict
(200, '<h1>Welcome</h1>'), # bad json
(403, '<h1>Bad creds</h1>'),
(404, '<h1>Not Found</h1>'),
(400, '{"message": "bad request"}'),
(400, '[{"message": "bad request"}]'),
(500, '<h1>Crash</h1>'),
):
requests_get.return_value = tests.utils.FakedResponse(
content=response[1], status_code=response[0]
)
resp = app.get('/okina/test/cities', status=200)
assert resp.json['err'] == 1
if resp.json['data'] and 'status_code' in resp.json['data']:
assert resp.json['data']['status_code'] == response[0]
# "normal" 401/403 response, ie problem with login/password
for status_code in (401, 403):
requests_get.return_value = tests.utils.FakedResponse(
content='''{"message": "Invalid credentials",
"code": 4, "status" : %d}'''
% status_code,
status_code=status_code,
)
resp = app.get('/okina/test/cities', status=200)
assert resp.json['err'] == 1
assert resp.json['err_desc'].startswith('Invalid credentials')
def test_okina_suscribe(app, okina):
for service in ('subscriber', 'subscription'):
endpoint = tests.utils.generic_endpoint_url('okina', service, slug=okina.slug)
assert endpoint == '/okina/test/%s' % service
with mock.patch('passerelle.utils.Request.get') as requests_get:
resp = app.post(endpoint, status=403)
assert requests_get.call_count == 0
assert resp.json['err'] == 1
assert resp.json['err_class'] == 'django.core.exceptions.PermissionDenied'
# open access
api = ApiUser.objects.create(username='all', keytype='', key='')
obj_type = ContentType.objects.get_for_model(okina)
AccessRight.objects.create(
codename='can_access', apiuser=api, resource_type=obj_type, resource_pk=okina.pk
)
for service in ('subscriber', 'subscription'):
endpoint = tests.utils.generic_endpoint_url('okina', service, slug=okina.slug)
assert endpoint == '/okina/test/%s' % service
with mock.patch('passerelle.utils.Request.post') as requests_get:
resp = app.post(endpoint, status=400) # no payload
assert requests_get.call_count == 0
assert resp.json['err'] == 1
assert resp.json['err_class'] == 'passerelle.utils.jsonresponse.APIError'
assert resp.json['err_desc'] == 'payload must be a JSON object'
resp = app.post_json(endpoint, params=[], status=400) # bad payload
assert requests_get.call_count == 0
assert resp.json['err'] == 1
assert resp.json['err_class'] == 'passerelle.utils.jsonresponse.APIError'
assert resp.json['err_desc'] == 'payload must be a dict'
requests_get.return_value = tests.utils.FakedResponse(content='{"foo":"bar"}', status_code=200)
resp = app.post_json(endpoint, params={'x': 'y'})
assert requests_get.call_count == 1
assert resp.json['err'] == 0
assert resp.json['data'] == {'foo': 'bar'}
# multiple subscriptions
endpoint = tests.utils.generic_endpoint_url('okina', 'subscription', slug=okina.slug)
with mock.patch('passerelle.utils.Request.post') as requests_post:
requests_post.return_value = tests.utils.FakedResponse(content='{"sub":"ok"}', status_code=200)
resp = app.post_json(endpoint, params={'lineIds': '1 ,2, 3', 'foo': 'bar'})
assert requests_post.call_count == 3
assert json.loads(requests_post.call_args_list[0][1]['data']) == {'foo': 'bar', 'lineId': '1'}
assert json.loads(requests_post.call_args_list[1][1]['data']) == {'foo': 'bar', 'lineId': '2'}
assert json.loads(requests_post.call_args_list[2][1]['data']) == {'foo': 'bar', 'lineId': '3'}
assert resp.json['err'] == 0
assert resp.json['data'] == [{'sub': 'ok'}, {'sub': 'ok'}, {'sub': 'ok'}]
# qrcode
endpoint = '/okina/test/subscriber/123/qrcode'
with mock.patch('passerelle.utils.Request.get') as requests_get:
requests_get.return_value = tests.utils.FakedResponse(
content='PNGfoo', headers={'Content-Type': 'image/png'}, status_code=200
)
resp = app.get(endpoint)
assert requests_get.call_count == 1
assert resp.headers['content-type'] == 'image/png'
assert resp.content == b'PNGfoo'
requests_get.return_value = tests.utils.FakedResponse(
content=QRCODE_400, headers={'Content-Type': 'application/json'}, status_code=400
)
resp = app.get(endpoint, status=200)
assert requests_get.call_count == 2
assert resp.json['err'] == 1
assert resp.json['err_desc'].startswith(
'Subscriber with ID 123 has no passcard number to generate qr code from.'
)
requests_get.return_value = tests.utils.FakedResponse(
content=QRCODE_404, headers={'Content-Type': 'application/json'}, status_code=404
)
resp = app.get(endpoint, status=200)
assert requests_get.call_count == 3
assert resp.json['err'] == 1
assert resp.json['err_desc'].startswith('Subscriber with ID 123 not found.')