Skip to content
Merged
2 changes: 2 additions & 0 deletions mapswipe_workers/mapswipe_workers/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,14 @@ def tutorial(self):
ClassificationTutorial,
CompletenessTutorial,
FootprintTutorial,
StreetTutorial,
)

project_type_classes = {
1: ClassificationTutorial,
2: FootprintTutorial,
3: ChangeDetectionTutorial,
4: CompletenessTutorial,
7: StreetTutorial,
}
return project_type_classes[self.value]
2 changes: 2 additions & 0 deletions mapswipe_workers/mapswipe_workers/project_types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from .arbitrary_geometry.footprint.tutorial import FootprintTutorial
from .media_classification.project import MediaClassificationProject
from .street.project import StreetProject
from .street.tutorial import StreetTutorial
from .tile_map_service.change_detection.project import ChangeDetectionProject
from .tile_map_service.change_detection.tutorial import ChangeDetectionTutorial
from .tile_map_service.classification.project import ClassificationProject
Expand All @@ -22,4 +23,5 @@
"FootprintTutorial",
"DigitizationProject",
"StreetProject",
"StreetTutorial",
]
80 changes: 75 additions & 5 deletions mapswipe_workers/mapswipe_workers/project_types/street/tutorial.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,84 @@
from dataclasses import asdict, dataclass

from mapswipe_workers.definitions import logger
from mapswipe_workers.firebase.firebase import Firebase
from mapswipe_workers.project_types.street.project import StreetGroup, StreetTask
from mapswipe_workers.project_types.tutorial import BaseTutorial


@dataclass
class StreetTutorialTask(StreetTask):
projectId: int
taskId: str
groupId: int
referenceAnswer: int
screen: int


class StreetTutorial(BaseTutorial):
"""The subclass for an TMS Grid based Tutorial."""
"""The subclass for an arbitrary geometry based Tutorial."""

def save_tutorial(self):
raise NotImplementedError("Currently Street has no Tutorial")
def __init__(self, tutorial_draft):
# this will create the basis attributes
super().__init__(tutorial_draft)

# self.projectId = tutorial_draft["projectId"]
self.projectType = tutorial_draft["projectType"]
self.tutorial_tasks = tutorial_draft["tutorialTasks"]
self.groups = dict()
self.tasks = dict()

def create_tutorial_groups(self):
raise NotImplementedError("Currently Street has no Tutorial")
"""Create group for the tutorial based on provided examples in geojson file."""
# load examples/tasks from file

group = StreetGroup(
groupId=101,
projectId=self.projectId,
numberOfTasks=len(self.tutorial_tasks),
progress=0,
finishedCount=0,
requiredCount=0,
)
self.groups[101] = group

# Add number of tasks for the group here. This needs to be set according to
# the number of features/examples in the geojson file

logger.info(
f"{self.projectId}"
f" - create_tutorial_groups - "
f"created groups dictionary"
)

def create_tutorial_tasks(self):
raise NotImplementedError("Currently Street has no Tutorial")
"""Create the tasks dict based on provided examples in geojson file."""
task_list = []
for i, task in enumerate(self.tutorial_tasks["features"]):
task = StreetTutorialTask(
projectId=self.projectId,
groupId=101,
taskId=f"{task['properties']['id']}",
geometry="",
referenceAnswer=task["properties"]["reference"],
screen=task["properties"]["screen"],
)
task_list.append(asdict(task))
if task_list:
self.tasks[101] = task_list
else:
logger.info(f"group in project {self.projectId} is not valid.")

logger.info(
f"{self.projectId}"
f" - create_tutorial_tasks - "
f"created tasks dictionary"
)

def save_tutorial(self):
firebase = Firebase()
firebase.save_tutorial_to_firebase(
self, self.groups, self.tasks, useCompression=True
)
logger.info(self.tutorialDraftId)
firebase.drop_tutorial_draft(self.tutorialDraftId)
1 change: 0 additions & 1 deletion mapswipe_workers/tests/fixtures/projectDrafts/street.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,5 @@
"requestingOrganisation": "test",
"verificationNumber": 3,
"groupSize": 25,
"startTimestamp": "2019-07-01T00:00:00.000Z",
"samplingThreshold": 0.1
}
110 changes: 110 additions & 0 deletions mapswipe_workers/tests/fixtures/tutorialDrafts/street.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
{
"createdBy": "atCSosZACaN0qhcVjtMO1tq9d1G3",
"tutorialDraftId": "test_tile_classification",
"informationPages": [
{
"blocks": [
{
"blockNumber": 1,
"blockType": "text",
"textDescription": "This is the first information page"
},
{
"blockNumber": 2,
"blockType": "image",
"image": "https://firebasestorage.googleapis.com/v0/b/dev-mapswipe.appspot.com/o/tutorialImages%2F1739963139725-block-image-2-1x1.png?alt=media&token=ae584dcd-d351-4bfe-be5f-1e0d38547f72"
}
],
"pageNumber": 1,
"title": "Information page 1"
}
],
"lookFor": "cobblestone",
"name": "cobblestone-tutorial",
"projectType": 7,
"screens": [
null,
{
"hint": {
"description": "This seems to be a tarmac surface.",
"icon": "check",
"title": "Tarmac"
},
"instructions": {
"description": "Check out if the road surface material is cobblestone here",
"icon": "check",
"title": "Is this cobblestone?"
},
"success": {
"description": "Correct, this is not cobblestone",
"icon": "check",
"title": "Nice!"
}
},
{
"hint": {
"description": "That surface does look like cobblestone!",
"icon": "heart-outline",
"title": "Cobblestone"
},
"instructions": {
"description": "Does this look like cobblestone?",
"icon": "egg-outline",
"title": "How about this one?"
},
"success": {
"description": "Correct",
"icon": "search-outline",
"title": "Correct"
}
}
],
"tileServer": {
"credits": "© 2019 Microsoft Corporation, Earthstar Geographics SIO",
"name": "bing"
},
"tutorialTasks": {
"crs": {
"properties": {
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
},
"type": "name"
},
"features": [
{
"geometry": {
"coordinates": [
13.4514123,
52.5103378,
0
],
"type": "Point"
},
"properties": {
"id": "1171343450849316",
"reference": 1,
"screen": 1
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
13.45285,
52.508467,
0
],
"type": "Point"
},
"properties": {
"id": "378811598610667",
"reference": 0,
"screen": 2
},
"type": "Feature"
}
],
"name": "cobblestone-scenario",
"type": "FeatureCollection"
}
}
55 changes: 41 additions & 14 deletions mapswipe_workers/tests/integration/set_up.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,28 @@


def set_firebase_test_data(
project_type: str, data_type: str, fixture_name: str, identifier: str
project_type: str,
data_type: str,
fixture_name: str,
identifier: str,
tutorial_id: str = None,
):
test_dir = os.path.dirname(__file__)
fixture_name = fixture_name + ".json"
file_path = os.path.join(
test_dir, "fixtures", project_type, data_type, fixture_name
)
upload_file_to_firebase(file_path, data_type, identifier)
upload_file_to_firebase(file_path, data_type, identifier, tutorial_id=tutorial_id)


def upload_file_to_firebase(file_path: str, data_type: str, identifier: str):
def upload_file_to_firebase(
file_path: str, data_type: str, identifier: str, tutorial_id: str = None
):
with open(file_path) as test_file:
test_data = json.load(test_file)

if tutorial_id:
test_data["tutorialId"] = tutorial_id
fb_db = auth.firebaseDB()
ref = fb_db.reference(f"/v2/{data_type}/{identifier}")
ref.set(test_data)
Expand Down Expand Up @@ -85,15 +93,20 @@ def create_test_project(
set_postgres_test_data(project_type, "users", "user")
set_firebase_test_data(project_type, "user_groups", "user_group", "")
set_firebase_test_data(project_type, "results", fixture_name, project_id)
set_postgres_test_data(project_type, "mapping_sessions", fixture_name, columns=[
"project_id",
"group_id",
"user_id",
"mapping_session_id",
"start_time",
"end_time",
"items_count",
])
set_postgres_test_data(
project_type,
"mapping_sessions",
fixture_name,
columns=[
"project_id",
"group_id",
"user_id",
"mapping_session_id",
"start_time",
"end_time",
"items_count",
],
)
set_postgres_test_data(project_type, mapping_sessions_results, fixture_name)
if create_user_group_session_data:
set_postgres_test_data(
Expand All @@ -108,7 +121,9 @@ def create_test_project(
"created_at",
],
)
set_postgres_test_data(project_type, "mapping_sessions_user_groups", fixture_name)
set_postgres_test_data(
project_type, "mapping_sessions_user_groups", fixture_name
)

time.sleep(5) # Wait for Firebase Functions to complete
return project_id
Expand All @@ -131,12 +146,24 @@ def create_test_user(project_type: str, user_id: str = None) -> str:


def create_test_project_draft(
project_type: str, fixture_name: str = "user", identifier: str = ""
project_type: str,
fixture_name: str = "user",
identifier: str = "",
tutorial_id: str = None,
) -> str:
"""
Create test project drafts in Firebase and return project ids.
Project drafts in Firebase are created by project manager using the dashboard.
"""
if tutorial_id:
set_firebase_test_data(
project_type,
"projectDrafts",
fixture_name,
identifier,
tutorial_id=tutorial_id,
)
return identifier
if not identifier:
identifier = f"test_{fixture_name}"
set_firebase_test_data(project_type, "projectDrafts", fixture_name, identifier)
Expand Down
8 changes: 7 additions & 1 deletion mapswipe_workers/tests/integration/tear_down.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from mapswipe_workers import auth


def delete_test_data(project_id: str) -> None:
def delete_test_data(project_id: str, tutorial_id: str = None) -> None:
"""
Delete test project indluding groups, tasks and results
from Firebase and Postgres
Expand Down Expand Up @@ -38,6 +38,12 @@ def delete_test_data(project_id: str) -> None:
ref = fb_db.reference(f"v2/users/{project_id}")
ref.delete()

if tutorial_id is not None:
ref = fb_db.reference(f"v2/projects/{tutorial_id}")
ref.delete()
ref = fb_db.reference(f"v2/tutorialDrafts/{tutorial_id}")
ref.delete()

# Clear out the user-group used in test.
# XXX: Use a firebase simulator for running test.
# For CI/CD, use a real firebase with scope using commit hash,
Expand Down
Loading