diff --git a/src/api/endpoints/annotate/_shared/extract.py b/src/api/endpoints/annotate/_shared/extract.py index 12368cd6..4a7517eb 100644 --- a/src/api/endpoints/annotate/_shared/extract.py +++ b/src/api/endpoints/annotate/_shared/extract.py @@ -28,18 +28,25 @@ async def extract_and_format_get_annotation_result( html_response_info = DTOConverter.html_content_list_to_html_response_info( url.html_content ) + # URL Types url_type_suggestions: list[URLTypeAnnotationSuggestion] = \ convert_user_url_type_suggestion_to_url_type_annotation_suggestion( - url.user_relevant_suggestions + url.user_url_type_suggestions, + url.anon_url_type_suggestions ) + # Record Types record_type_suggestions: RecordTypeAnnotationResponseOuterInfo = \ convert_user_record_type_suggestion_to_record_type_annotation_suggestion( - url.user_record_type_suggestions + url.user_record_type_suggestions, + url.anon_record_type_suggestions ) + # Agencies agency_suggestions: AgencyAnnotationResponseOuterInfo = \ await GetAgencySuggestionsQueryBuilder(url_id=url.id).run(session) + # Locations location_suggestions: LocationAnnotationResponseOuterInfo = \ await GetLocationSuggestionsQueryBuilder(url_id=url.id).run(session) + # Names name_suggestions: NameAnnotationResponseOuterInfo = \ await GetNameSuggestionsQueryBuilder(url_id=url.id).run(session) return GetNextURLForAllAnnotationResponse( diff --git a/src/api/endpoints/annotate/_shared/queries/helper.py b/src/api/endpoints/annotate/_shared/queries/helper.py index 3f3745f5..f8bdf033 100644 --- a/src/api/endpoints/annotate/_shared/queries/helper.py +++ b/src/api/endpoints/annotate/_shared/queries/helper.py @@ -47,9 +47,10 @@ def conclude(query: Select) -> Select: # Add load options query.options( joinedload(URL.html_content), - joinedload(URL.user_relevant_suggestions), + joinedload(URL.user_url_type_suggestions), joinedload(URL.user_record_type_suggestions), - joinedload(URL.name_suggestions), + joinedload(URL.anon_record_type_suggestions), + joinedload(URL.anon_url_type_suggestions), ) # Sorting Priority .order_by( diff --git a/src/api/endpoints/annotate/all/get/queries/agency/requester.py b/src/api/endpoints/annotate/all/get/queries/agency/requester.py index 68d801b5..8c50b41d 100644 --- a/src/api/endpoints/annotate/all/get/queries/agency/requester.py +++ b/src/api/endpoints/annotate/all/get/queries/agency/requester.py @@ -8,6 +8,7 @@ from src.db.helpers.query import exists_url from src.db.helpers.session import session_helper as sh from src.db.models.impl.agency.sqlalchemy import Agency +from src.db.models.impl.annotation.agency.anon.sqlalchemy import AnnotationAgencyAnon from src.db.models.impl.annotation.agency.auto.subtask.sqlalchemy import AnnotationAgencyAutoSubtask from src.db.models.impl.annotation.agency.auto.suggestion.sqlalchemy import AnnotationAgencyAutoSuggestion from src.db.models.impl.annotation.agency.user.sqlalchemy import AnnotationAgencyUser @@ -40,6 +41,9 @@ async def get_agency_suggestions(self) -> list[SuggestionModel]: ), exists_url( AnnotationAgencyAutoSubtask + ), + exists_url( + AnnotationAgencyAnon ) ) ) @@ -60,6 +64,20 @@ async def get_agency_suggestions(self) -> list[SuggestionModel]: .cte("user_suggestions") ) + # Number of anon users who suggested each agency + anon_suggestions_cte = ( + select( + AnnotationAgencyAnon.url_id, + AnnotationAgencyAnon.agency_id, + func.count(AnnotationAgencyAnon.session_id).label('anon_count') + ) + .group_by( + AnnotationAgencyAnon.agency_id, + AnnotationAgencyAnon.url_id, + ) + .cte("anon_suggestions") + ) + # Maximum confidence of robo annotation, if any robo_suggestions_cte = ( select( @@ -88,6 +106,7 @@ async def get_agency_suggestions(self) -> list[SuggestionModel]: Agency.name.label("display_name"), func.coalesce(user_suggestions_cte.c.user_count, 0).label('user_count'), func.coalesce(robo_suggestions_cte.c.robo_confidence, 0).label('robo_confidence'), + func.coalesce(anon_suggestions_cte.c.anon_count, 0).label('anon_count'), ) .join( Agency, @@ -100,6 +119,13 @@ async def get_agency_suggestions(self) -> list[SuggestionModel]: user_suggestions_cte.c.agency_id == Agency.id ) ) + .outerjoin( + anon_suggestions_cte, + and_( + anon_suggestions_cte.c.url_id == self.url_id, + anon_suggestions_cte.c.agency_id == Agency.id + ) + ) .outerjoin( robo_suggestions_cte, and_( @@ -110,7 +136,8 @@ async def get_agency_suggestions(self) -> list[SuggestionModel]: .where( or_( user_suggestions_cte.c.user_count > 0, - robo_suggestions_cte.c.robo_confidence > 0 + robo_suggestions_cte.c.robo_confidence > 0, + anon_suggestions_cte.c.anon_count > 0 ) ) ) @@ -119,7 +146,10 @@ async def get_agency_suggestions(self) -> list[SuggestionModel]: mappings: Sequence[RowMapping] = await self.mappings(joined_suggestions_query) suggestions: list[SuggestionModel] = [ SuggestionModel( - **mapping + id=mapping["id"], + display_name=mapping["display_name"], + user_count=mapping['user_count'] + (mapping['anon_count'] // 2), + robo_confidence=mapping["robo_confidence"] ) for mapping in mappings ] diff --git a/src/api/endpoints/annotate/all/get/queries/convert.py b/src/api/endpoints/annotate/all/get/queries/convert.py index 80625d3c..fedfa8a2 100644 --- a/src/api/endpoints/annotate/all/get/queries/convert.py +++ b/src/api/endpoints/annotate/all/get/queries/convert.py @@ -1,43 +1,55 @@ +import math from collections import Counter from src.api.endpoints.annotate.all.get.models.record_type import RecordTypeAnnotationResponseOuterInfo, \ RecordTypeSuggestionModel from src.api.endpoints.annotate.all.get.models.url_type import URLTypeAnnotationSuggestion from src.core.enums import RecordType +from src.db.models.impl.annotation.record_type.anon.sqlalchemy import AnnotationRecordTypeAnon +from src.db.models.impl.annotation.url_type.anon.sqlalchemy import AnnotationURLTypeAnon from src.db.models.impl.flag.url_validated.enums import URLType from src.db.models.impl.annotation.record_type.user.user import AnnotationRecordTypeUser from src.db.models.impl.annotation.url_type.user.sqlalchemy import AnnotationURLTypeUser def convert_user_url_type_suggestion_to_url_type_annotation_suggestion( - db_suggestions: list[AnnotationURLTypeUser] + user_suggestions: list[AnnotationURLTypeUser], + anon_suggestions: list[AnnotationURLTypeAnon] ) -> list[URLTypeAnnotationSuggestion]: counter: Counter[URLType] = Counter() - for suggestion in db_suggestions: + for suggestion in user_suggestions: counter[suggestion.type] += 1 + + for suggestion in anon_suggestions: + counter[suggestion.url_type] += 0.5 + anno_suggestions: list[URLTypeAnnotationSuggestion] = [] for url_type, endorsement_count in counter.most_common(3): anno_suggestions.append( URLTypeAnnotationSuggestion( url_type=url_type, - endorsement_count=endorsement_count, + endorsement_count=math.floor(endorsement_count), ) ) return anno_suggestions def convert_user_record_type_suggestion_to_record_type_annotation_suggestion( - db_suggestions: list[AnnotationRecordTypeUser] + user_suggestions: list[AnnotationRecordTypeUser], + anon_suggestions: list[AnnotationRecordTypeAnon] ) -> RecordTypeAnnotationResponseOuterInfo: counter: Counter[RecordType] = Counter() - for suggestion in db_suggestions: + for suggestion in user_suggestions: counter[suggestion.record_type] += 1 + for suggestion in anon_suggestions: + counter[suggestion.record_type] += 0.5 + suggestions: list[RecordTypeSuggestionModel] = [] for record_type, endorsement_count in counter.most_common(3): suggestions.append( RecordTypeSuggestionModel( record_type=record_type, - user_count=endorsement_count, + user_count=math.floor(endorsement_count), robo_confidence=0, ) ) diff --git a/src/api/endpoints/annotate/all/get/queries/location_/core.py b/src/api/endpoints/annotate/all/get/queries/location_/core.py index 6081c5f7..5d03bc55 100644 --- a/src/api/endpoints/annotate/all/get/queries/location_/core.py +++ b/src/api/endpoints/annotate/all/get/queries/location_/core.py @@ -15,7 +15,6 @@ def __init__( super().__init__() self.url_id = url_id - # TODO: Test async def run(self, session: AsyncSession) -> LocationAnnotationResponseOuterInfo: requester = GetLocationSuggestionsRequester(session) diff --git a/src/api/endpoints/annotate/all/get/queries/location_/requester.py b/src/api/endpoints/annotate/all/get/queries/location_/requester.py index 49f00f89..b8ba5410 100644 --- a/src/api/endpoints/annotate/all/get/queries/location_/requester.py +++ b/src/api/endpoints/annotate/all/get/queries/location_/requester.py @@ -6,6 +6,7 @@ from src.api.endpoints.annotate.all.get.queries._shared.sort import sort_suggestions from src.db.helpers.query import exists_url from src.db.helpers.session import session_helper as sh +from src.db.models.impl.annotation.location.anon.sqlalchemy import AnnotationLocationAnon from src.db.models.impl.annotation.location.auto.subtask.sqlalchemy import AnnotationLocationAutoSubtask from src.db.models.impl.annotation.location.auto.suggestion.sqlalchemy import AnnotationLocationAutoSuggestion from src.db.models.impl.annotation.location.user.sqlalchemy import AnnotationLocationUser @@ -29,6 +30,9 @@ async def get_location_suggestions(self, url_id: int) -> list[SuggestionModel]: ), exists_url( AnnotationLocationAutoSubtask + ), + exists_url( + AnnotationLocationAnon ) ) ) @@ -47,6 +51,20 @@ async def get_location_suggestions(self, url_id: int) -> list[SuggestionModel]: ) .cte("user_suggestions") ) + # Number of anon users who suggested each location + anon_suggestions_cte = ( + select( + AnnotationLocationAnon.url_id, + AnnotationLocationAnon.location_id, + func.count(AnnotationLocationAnon.session_id).label('anon_count') + ) + .group_by( + AnnotationLocationAnon.location_id, + AnnotationLocationAnon.url_id, + ) + .cte("anon_suggestions") + ) + # Maximum confidence of robo annotation, if any robo_suggestions_cte = ( select( @@ -75,6 +93,7 @@ async def get_location_suggestions(self, url_id: int) -> list[SuggestionModel]: LocationExpandedView.full_display_name.label("display_name"), func.coalesce(user_suggestions_cte.c.user_count, 0).label("user_count"), func.coalesce(robo_suggestions_cte.c.robo_confidence, 0).label("robo_confidence"), + func.coalesce(anon_suggestions_cte.c.anon_count, 0).label("anon_count"), ) .join( LocationExpandedView, @@ -87,6 +106,13 @@ async def get_location_suggestions(self, url_id: int) -> list[SuggestionModel]: user_suggestions_cte.c.location_id == LocationExpandedView.id ) ) + .outerjoin( + anon_suggestions_cte, + and_( + anon_suggestions_cte.c.url_id == url_id, + anon_suggestions_cte.c.location_id == LocationExpandedView.id + ) + ) .outerjoin( robo_suggestions_cte, and_( @@ -97,7 +123,8 @@ async def get_location_suggestions(self, url_id: int) -> list[SuggestionModel]: .where( or_( user_suggestions_cte.c.user_count > 0, - robo_suggestions_cte.c.robo_confidence > 0 + robo_suggestions_cte.c.robo_confidence > 0, + anon_suggestions_cte.c.anon_count > 0 ) ) ) @@ -105,7 +132,10 @@ async def get_location_suggestions(self, url_id: int) -> list[SuggestionModel]: mappings: Sequence[RowMapping] = await self.mappings(joined_suggestions_query) suggestions: list[SuggestionModel] = [ SuggestionModel( - **mapping + id=mapping["id"], + display_name=mapping["display_name"], + user_count=mapping['user_count'] + (mapping['anon_count'] // 2), + robo_confidence=mapping["robo_confidence"] ) for mapping in mappings ] diff --git a/src/api/endpoints/annotate/all/get/queries/name/core.py b/src/api/endpoints/annotate/all/get/queries/name/core.py index 3cc1324d..b41ee4fd 100644 --- a/src/api/endpoints/annotate/all/get/queries/name/core.py +++ b/src/api/endpoints/annotate/all/get/queries/name/core.py @@ -5,6 +5,7 @@ from src.api.endpoints.annotate.all.get.models.name import NameAnnotationSuggestion, NameAnnotationResponseOuterInfo from src.db.helpers.session import session_helper as sh +from src.db.models.impl.annotation.name.anon.sqlalchemy import AnnotationNameAnonEndorsement from src.db.models.impl.annotation.name.suggestion.enums import NameSuggestionSource from src.db.models.impl.annotation.name.suggestion.sqlalchemy import AnnotationNameSuggestion from src.db.models.impl.annotation.name.user.sqlalchemy import AnnotationNameUserEndorsement @@ -28,6 +29,9 @@ async def run(self, session: AsyncSession) -> NameAnnotationResponseOuterInfo: func.count( AnnotationNameUserEndorsement.user_id ).label('user_count'), + func.count( + AnnotationNameAnonEndorsement.session_id + ).label('anon_count'), case( (AnnotationNameSuggestion.source == NameSuggestionSource.HTML_METADATA_TITLE, 1), else_=0 @@ -37,6 +41,10 @@ async def run(self, session: AsyncSession) -> NameAnnotationResponseOuterInfo: AnnotationNameUserEndorsement, AnnotationNameUserEndorsement.suggestion_id == AnnotationNameSuggestion.id, ) + .outerjoin( + AnnotationNameAnonEndorsement, + AnnotationNameAnonEndorsement.suggestion_id == AnnotationNameSuggestion.id, + ) .where( AnnotationNameSuggestion.url_id == self.url_id, ) @@ -45,7 +53,9 @@ async def run(self, session: AsyncSession) -> NameAnnotationResponseOuterInfo: AnnotationNameSuggestion.suggestion, ) .order_by( - func.count(AnnotationNameUserEndorsement.user_id).desc(), + (func.count(AnnotationNameUserEndorsement.user_id) + func.count( + AnnotationNameUserEndorsement.user_id + )).desc(), AnnotationNameSuggestion.id.asc(), ) .limit(3) @@ -54,7 +64,10 @@ async def run(self, session: AsyncSession) -> NameAnnotationResponseOuterInfo: mappings: Sequence[RowMapping] = await sh.mappings(session, query=query) suggestions = [ NameAnnotationSuggestion( - **mapping + id=mapping["id"], + display_name=mapping["display_name"], + user_count=mapping['user_count'] + (mapping['anon_count'] // 2), + robo_count=mapping["robo_count"] ) for mapping in mappings ] diff --git a/src/api/endpoints/pending/__init__.py b/src/api/endpoints/pending/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/api/endpoints/pending/agencies/__init__.py b/src/api/endpoints/pending/agencies/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/api/endpoints/pending/agencies/approve/__init__.py b/src/api/endpoints/pending/agencies/approve/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/api/endpoints/pending/agencies/get/__init__.py b/src/api/endpoints/pending/agencies/get/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/api/endpoints/pending/routes.py b/src/api/endpoints/pending/routes.py new file mode 100644 index 00000000..e69de29b diff --git a/src/db/models/impl/agency/sqlalchemy.py b/src/db/models/impl/agency/sqlalchemy.py index a6c9c1cf..d6ccbc3b 100644 --- a/src/db/models/impl/agency/sqlalchemy.py +++ b/src/db/models/impl/agency/sqlalchemy.py @@ -2,7 +2,7 @@ References an agency in the data sources database. """ -from sqlalchemy import Column, Integer, String, DateTime, Sequence +from sqlalchemy import Column, String from sqlalchemy.orm import relationship, Mapped from src.db.models.helpers import enum_column diff --git a/src/db/models/impl/annotation/url_type/auto/sqlalchemy.py b/src/db/models/impl/annotation/url_type/auto/sqlalchemy.py index cc5fb7b8..d882f667 100644 --- a/src/db/models/impl/annotation/url_type/auto/sqlalchemy.py +++ b/src/db/models/impl/annotation/url_type/auto/sqlalchemy.py @@ -25,4 +25,4 @@ class AnnotationAutoURLType( # Relationships - url = relationship("URL", back_populates="auto_relevant_suggestion") + url = relationship("URL") diff --git a/src/db/models/impl/annotation/url_type/user/sqlalchemy.py b/src/db/models/impl/annotation/url_type/user/sqlalchemy.py index 8f02a65d..1d71483a 100644 --- a/src/db/models/impl/annotation/url_type/user/sqlalchemy.py +++ b/src/db/models/impl/annotation/url_type/user/sqlalchemy.py @@ -29,4 +29,4 @@ class AnnotationURLTypeUser( # Relationships - url = relationship("URL", back_populates="user_relevant_suggestions") + url = relationship("URL") diff --git a/src/db/models/impl/url/core/sqlalchemy.py b/src/db/models/impl/url/core/sqlalchemy.py index a4295ae3..45e8b45b 100644 --- a/src/db/models/impl/url/core/sqlalchemy.py +++ b/src/db/models/impl/url/core/sqlalchemy.py @@ -4,11 +4,16 @@ from src.collectors.enums import URLStatus from src.db.models.helpers import enum_column +from src.db.models.impl.annotation.agency.anon.sqlalchemy import AnnotationAgencyAnon from src.db.models.impl.annotation.agency.auto.subtask.sqlalchemy import AnnotationAgencyAutoSubtask from src.db.models.impl.annotation.agency.user.sqlalchemy import AnnotationAgencyUser +from src.db.models.impl.annotation.location.anon.sqlalchemy import AnnotationLocationAnon from src.db.models.impl.annotation.location.auto.subtask.sqlalchemy import AnnotationLocationAutoSubtask from src.db.models.impl.annotation.location.user.sqlalchemy import AnnotationLocationUser +from src.db.models.impl.annotation.name.anon.sqlalchemy import AnnotationNameAnonEndorsement from src.db.models.impl.annotation.name.suggestion.sqlalchemy import AnnotationNameSuggestion +from src.db.models.impl.annotation.record_type.anon.sqlalchemy import AnnotationRecordTypeAnon +from src.db.models.impl.annotation.url_type.anon.sqlalchemy import AnnotationURLTypeAnon from src.db.models.impl.link.user_suggestion_not_found.location.sqlalchemy import LinkUserSuggestionLocationNotFound from src.db.models.impl.url.checked_for_duplicate import URLCheckedForDuplicate from src.db.models.impl.url.core.enums import URLSource @@ -107,23 +112,30 @@ def full_url(cls): auto_location_subtasks = relationship( AnnotationLocationAutoSubtask ) + anon_location_suggestions = relationship( + AnnotationLocationAnon) # Agency user_agency_suggestions = relationship( AnnotationAgencyUser, back_populates="url") auto_agency_subtasks = relationship( - AnnotationAgencyAutoSubtask - ) + AnnotationAgencyAutoSubtask) + anon_agency_suggestions = relationship( + AnnotationAgencyAnon) # Record Type auto_record_type_suggestion = relationship( AnnotationAutoRecordType, uselist=False, back_populates="url") user_record_type_suggestions = relationship( AnnotationRecordTypeUser, back_populates="url") + anon_record_type_suggestions = relationship( + AnnotationRecordTypeAnon) # Relvant/URL Type - auto_relevant_suggestion = relationship( + auto_url_type_suggestions = relationship( AnnotationAutoURLType, uselist=False, back_populates="url") - user_relevant_suggestions = relationship( + user_url_type_suggestions = relationship( AnnotationURLTypeUser, back_populates="url") + anon_url_type_suggestions = relationship( + AnnotationURLTypeAnon) reviewing_user = relationship( "ReviewingUserURL", uselist=False, back_populates="url") diff --git a/tests/automated/integration/api/annotate/all/test_anon_count.py b/tests/automated/integration/api/annotate/all/test_anon_count.py new file mode 100644 index 00000000..16fe728b --- /dev/null +++ b/tests/automated/integration/api/annotate/all/test_anon_count.py @@ -0,0 +1,124 @@ +import pytest +import uuid + +from src.api.endpoints.annotate.all.get.models.response import GetNextURLForAllAnnotationResponse +from src.core.enums import RecordType +from src.db.models.impl.annotation.agency.anon.sqlalchemy import AnnotationAgencyAnon +from src.db.models.impl.annotation.location.anon.sqlalchemy import AnnotationLocationAnon +from src.db.models.impl.annotation.name.anon.sqlalchemy import AnnotationNameAnonEndorsement +from src.db.models.impl.annotation.name.suggestion.enums import NameSuggestionSource +from src.db.models.impl.annotation.name.suggestion.sqlalchemy import AnnotationNameSuggestion +from src.db.models.impl.annotation.record_type.anon.sqlalchemy import AnnotationRecordTypeAnon +from src.db.models.impl.annotation.url_type.anon.sqlalchemy import AnnotationURLTypeAnon +from src.db.models.impl.anon_session.sqlalchemy import AnonymousSession +from src.db.models.impl.flag.url_validated.enums import URLType +from tests.helpers.data_creator.models.creation_info.us_state import USStateCreationInfo +from tests.helpers.setup.final_review.core import setup_for_get_next_url_for_final_review + + +@pytest.mark.asyncio +async def test_anon_count( + api_test_helper, + test_agency_id: int, + pennsylvania: USStateCreationInfo, +): + """ + Test that the user annotation counts are updated correctly + when anonymous annotations are added. + """ + ath = api_test_helper + adb_client = ath.adb_client() + + # Set up URLs + setup_info_1 = await setup_for_get_next_url_for_final_review( + db_data_creator=ath.db_data_creator, include_user_annotations=True + ) + url_id: int = setup_info_1.url_mapping.url_id + + # Add anonymous sessions + anon_sessions: list[AnonymousSession] = [] + for i in range(12): + anon_session = AnonymousSession( + id=uuid.uuid4(), + ) + anon_sessions.append(anon_session) + await adb_client.add_all(anon_sessions) + + def get_anon_session_id(i: int) -> uuid.UUID: + return anon_sessions[i].id + + + # URL Types + url_type_annotations: list[AnnotationURLTypeAnon] = [] + for i in range(3): + url_type_annotation = AnnotationURLTypeAnon( + url_id=url_id, + session_id=get_anon_session_id(i), + url_type=URLType.DATA_SOURCE + ) + url_type_annotations.append(url_type_annotation) + await adb_client.add_all(url_type_annotations) + + + + # Record Types + record_type_annotations: list[AnnotationRecordTypeAnon] = [] + for i in range(5): + record_type_annotation = AnnotationRecordTypeAnon( + url_id=url_id, + session_id=get_anon_session_id(i), + record_type=RecordType.CAR_GPS + ) + record_type_annotations.append(record_type_annotation) + await adb_client.add_all(record_type_annotations) + + + + # Agencies + agency_annotations: list[AnnotationAgencyAnon] = [] + for i in range(7): + agency_annotation = AnnotationAgencyAnon( + url_id=url_id, + agency_id=test_agency_id, + session_id=get_anon_session_id(i) + ) + agency_annotations.append(agency_annotation) + await adb_client.add_all(agency_annotations) + + + # Locations + location_annotations: list[AnnotationLocationAnon] = [] + for i in range(9): + location_annotation = AnnotationLocationAnon( + url_id=url_id, + session_id=get_anon_session_id(i), + location_id=pennsylvania.location_id, + ) + location_annotations.append(location_annotation) + await adb_client.add_all(location_annotations) + + # Name + name_suggestion = AnnotationNameSuggestion( + url_id=url_id, + suggestion="Test Name", + source=NameSuggestionSource.USER, + ) + name_suggestion_id = await adb_client.add(name_suggestion, return_id=True) + + name_annotations: list[AnnotationNameAnonEndorsement] = [] + for i in range(11): + name_annotation = AnnotationNameAnonEndorsement( + suggestion_id=name_suggestion_id, + session_id=get_anon_session_id(i), + ) + name_annotations.append(name_annotation) + await adb_client.add_all(name_annotations) + + # Check that the counts are correct + get_response_1: GetNextURLForAllAnnotationResponse = await ath.request_validator.get_next_url_for_all_annotations() + assert get_response_1.next_annotation is not None + assert get_response_1.next_annotation.name_suggestions.suggestions[1].user_count == 5 + assert get_response_1.next_annotation.location_suggestions.suggestions[0].user_count == 4 + assert get_response_1.next_annotation.agency_suggestions.suggestions[0].user_count == 3 + assert get_response_1.next_annotation.record_type_suggestions.suggestions[0].user_count == 2 + assert get_response_1.next_annotation.url_type_suggestions[0].endorsement_count == 1 diff --git a/tests/automated/integration/api/annotate/all/test_happy_path.py b/tests/automated/integration/api/annotate/all/test_happy_path.py index 0ed29def..a356fa56 100644 --- a/tests/automated/integration/api/annotate/all/test_happy_path.py +++ b/tests/automated/integration/api/annotate/all/test_happy_path.py @@ -46,7 +46,7 @@ async def test_annotate_all( url_mapping_2 = setup_info_2.url_mapping # Get a valid URL to annotate - get_response_1 = await ath.request_validator.get_next_url_for_all_annotations() + get_response_1: GetNextURLForAllAnnotationResponse = await ath.request_validator.get_next_url_for_all_annotations() assert get_response_1.next_annotation is not None assert len(get_response_1.next_annotation.name_suggestions.suggestions) == 1 name_suggestion = get_response_1.next_annotation.name_suggestions.suggestions[0] diff --git a/tests/automated/integration/api/pending/__init__.py b/tests/automated/integration/api/pending/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/automated/integration/api/pending/test_agencies.py b/tests/automated/integration/api/pending/test_agencies.py new file mode 100644 index 00000000..24061804 --- /dev/null +++ b/tests/automated/integration/api/pending/test_agencies.py @@ -0,0 +1,16 @@ +import pytest + +from tests.helpers.api_test_helper import APITestHelper + + +@pytest.mark.asyncio +async def test_agencies(api_test_helper: APITestHelper): + pass + + # Add pending agency + + # Call GET endpoint + + # Call APPROVE endpoint + + # Check agency is added