diff --git a/app/model/document.py b/app/model/document.py index 9e31954b..9ac25615 100644 --- a/app/model/document.py +++ b/app/model/document.py @@ -24,9 +24,8 @@ class DocumentReadDTO(BaseModel): cdn_object: Optional[str] source_url: Optional[str] content_type: Optional[str] - user_language_name: str - # TODO: Languages for a document - # languages: list[] + user_language_name: Optional[str] + calc_language_name: Optional[str] class DocumentWriteDTO(BaseModel): @@ -38,9 +37,7 @@ class DocumentWriteDTO(BaseModel): type: Optional[str] title: str source_url: Optional[str] - user_language_name: str - # TODO: Languages for a document - # languages: list[] + user_language_name: Optional[str] class DocumentCreateDTO(BaseModel): @@ -56,8 +53,6 @@ class DocumentCreateDTO(BaseModel): title: str source_url: str user_language_name: str - # TODO: Languages for a document - # languages: list[] class DocumentUploadRequest(BaseModel): diff --git a/app/repository/document.py b/app/repository/document.py index 113ade03..569c5e70 100644 --- a/app/repository/document.py +++ b/app/repository/document.py @@ -1,15 +1,10 @@ from typing import Tuple import logging from typing import Optional, cast -from sqlalchemy.orm import Session, Query -from sqlalchemy import Column from app.clients.db.models.app.counters import CountedEntity from app.clients.db.models.law_policy.family import ( DocumentStatus, - FamilyDocumentRole, - FamilyDocumentType, Slug, - Variant, ) from app.errors import RepositoryError, ValidationError from app.model.document import DocumentCreateDTO, DocumentReadDTO, DocumentWriteDTO @@ -22,10 +17,13 @@ from app.clients.db.models.law_policy import ( FamilyDocument, ) -from sqlalchemy.exc import NoResultFound -from sqlalchemy import or_, update as db_update +from sqlalchemy import Column, or_, and_, update as db_update, insert as db_insert from sqlalchemy_utils import escape_like +from sqlalchemy.exc import NoResultFound +from sqlalchemy.orm import Session, Query, aliased +from sqlalchemy.sql.functions import concat +from sqlalchemy import func from app.repository.helpers import generate_import_id, generate_slug from app.repository import family as family_repo @@ -33,44 +31,72 @@ _LOGGER = logging.getLogger(__name__) -DocumentTuple = Tuple[FamilyDocument, PhysicalDocument, Slug] CreateObjects = Tuple[PhysicalDocumentLanguage, FamilyDocument, PhysicalDocument] def _get_query(db: Session) -> Query: - # NOTE: SqlAlchemy will make a complete hash of the query generation - # if columns are used in the query() call. Therefore, entire - # objects are returned. + lang_model = aliased(Language) + lang_user = aliased(Language) + pdl_model = aliased(PhysicalDocumentLanguage) + pdl_user = aliased(PhysicalDocumentLanguage) + + sq_slug = ( + db.query( + func.string_agg(Slug.name, ",").label("name"), + Slug.family_document_import_id.label("doc_id"), + ) + .group_by(Slug.family_document_import_id) + .subquery() + ) - # FIXME: TODO: will this work with multiple slugs???? return ( - db.query(FamilyDocument, PhysicalDocument, Slug) + db.query( + FamilyDocument.import_id.label("import_id"), + FamilyDocument.family_import_id.label("family_import_id"), + FamilyDocument.variant_name.label("variant_name"), + FamilyDocument.document_status.label("status"), + FamilyDocument.document_role.label("role"), + FamilyDocument.document_type.label("type"), + concat(sq_slug.c.name).label("slug"), + PhysicalDocument.id.label("physical_id"), + PhysicalDocument.title.label("title"), + PhysicalDocument.md5_sum.label("md5_sum"), + PhysicalDocument.cdn_object.label("cdn_object"), + PhysicalDocument.source_url.label("source_url"), + PhysicalDocument.content_type.label("content_type"), + lang_user.name.label("user_language_name"), + lang_model.name.label("calc_language_name"), + ) + .select_from(FamilyDocument, PhysicalDocument) .filter(FamilyDocument.physical_document_id == PhysicalDocument.id) + .join(sq_slug, sq_slug.c.doc_id == FamilyDocument.import_id, isouter=True) .join( - Slug, - Slug.family_document_import_id == FamilyDocument.import_id, + pdl_user, + and_( + PhysicalDocument.id == pdl_user.document_id, + pdl_user.source == LanguageSource.USER, + ), isouter=True, ) - ) - - -def _document_to_dto(doc_tuple: DocumentTuple) -> DocumentReadDTO: - fd, pd, slug = doc_tuple - return DocumentReadDTO( - import_id=cast(str, fd.import_id), - family_import_id=cast(str, fd.family_import_id), - variant_name=cast(Variant, fd.variant_name), - status=cast(DocumentStatus, fd.document_status), - role=cast(FamilyDocumentRole, fd.document_role), - type=cast(FamilyDocumentType, fd.document_type), - slug=cast(str, slug.name) if slug is not None else "", - physical_id=cast(int, pd.id), - title=cast(str, pd.title), - md5_sum=cast(str, pd.md5_sum), - cdn_object=cast(str, pd.cdn_object), - source_url=cast(str, pd.source_url), - content_type=cast(str, pd.content_type), - user_language_name="TODO", + .join( + lang_user, + lang_user.id == pdl_user.language_id, + isouter=True, + ) + .join( + pdl_model, + and_( + PhysicalDocument.id == pdl_model.document_id, + pdl_model.source == LanguageSource.MODEL, + ), + isouter=True, + ) + .join( + lang_model, + lang_model.id == pdl_model.language_id, + isouter=True, + ) + .distinct(FamilyDocument.import_id) ) @@ -109,14 +135,12 @@ def all(db: Session) -> list[DocumentReadDTO]: :param db Session: the database connection :return Optional[DocumentResponse]: All of things """ - doc_tuples = _get_query(db).all() + result = _get_query(db).all() - if not doc_tuples: + if not result: return [] - result = [_document_to_dto(d) for d in doc_tuples] - - return result + return [DocumentReadDTO(**dict(r)) for r in result] def get(db: Session, import_id: str) -> Optional[DocumentReadDTO]: @@ -128,12 +152,12 @@ def get(db: Session, import_id: str) -> Optional[DocumentReadDTO]: :return Optional[DocumentResponse]: A single document or nothing """ try: - doc_tuple = _get_query(db).filter(FamilyDocument.import_id == import_id).one() + result = _get_query(db).filter(FamilyDocument.import_id == import_id).one() except NoResultFound as e: _LOGGER.error(e) return - return _document_to_dto(doc_tuple) + return DocumentReadDTO(**dict(result)) def search(db: Session, search_term: str) -> list[DocumentReadDTO]: @@ -146,9 +170,9 @@ def search(db: Session, search_term: str) -> list[DocumentReadDTO]: """ term = f"%{escape_like(search_term)}%" search = or_(PhysicalDocument.title.ilike(term)) - found = _get_query(db).filter(search).all() + result = _get_query(db).filter(search).all() - return [_document_to_dto(d) for d in found] + return [DocumentReadDTO(**dict(r)) for r in result] def update(db: Session, import_id: str, document: DocumentWriteDTO) -> bool: @@ -160,7 +184,6 @@ def update(db: Session, import_id: str, document: DocumentWriteDTO) -> bool: :param DocumentDTO document: The new values :return bool: True if new values were set otherwise false. """ - # TODO: Implement this: new_values = document.model_dump() @@ -186,6 +209,17 @@ def update(db: Session, import_id: str, document: DocumentWriteDTO) -> bool: ) return False + # User Language changed? + pdl = ( + db.query(PhysicalDocumentLanguage) + .filter( + PhysicalDocumentLanguage.document_id == original_fd.physical_document_id + ) + .filter(PhysicalDocumentLanguage.source == LanguageSource.USER) + .one_or_none() + ) + new_language = _get_new_language(db, new_values, pdl) + update_slug = original_pd.title != new_values["title"] commands = [ @@ -204,6 +238,27 @@ def update(db: Session, import_id: str, document: DocumentWriteDTO) -> bool: ), ] + if new_language is not None: + if pdl is not None: + command = ( + db_update(PhysicalDocumentLanguage) + .where( + and_( + PhysicalDocumentLanguage.document_id + == original_fd.physical_document_id, + PhysicalDocumentLanguage.source == LanguageSource.USER, + ) + ) + .values(language_id=new_language.id) + ) + else: + command = db_insert(PhysicalDocumentLanguage).values( + document_id=original_fd.physical_document_id, + language_id=new_language.id, + source=LanguageSource.USER, + ) + commands.append(command) + for c in commands: result = db.execute(c) @@ -222,6 +277,26 @@ def update(db: Session, import_id: str, document: DocumentWriteDTO) -> bool: return True +def _get_new_language( + db: Session, new_values: dict, pdl: PhysicalDocumentLanguage +) -> Optional[Language]: + requested_language = new_values["user_language_name"] + if requested_language is None: + return None + else: + new_language = ( + db.query(Language) + .filter(Language.name == new_values["user_language_name"]) + .one() + ) + update_language = ( + pdl.language_id != new_language.id if pdl is not None else True + ) + + if update_language: + return new_language + + def create(db: Session, document: DocumentCreateDTO) -> str: """ Creates a new document. @@ -316,7 +391,7 @@ def count(db: Session) -> Optional[int]: :return Optional[int]: The number of documents in the repository or none. """ try: - n_documents = _get_query(db).count() + n_documents = db.query(FamilyDocument).count() except NoResultFound as e: _LOGGER.error(e) return diff --git a/integration_tests/blank.sql b/integration_tests/blank.sql index 0e94ec30..db5344c0 100644 --- a/integration_tests/blank.sql +++ b/integration_tests/blank.sql @@ -2,8 +2,8 @@ -- PostgreSQL database dump -- --- Dumped from database version 14.8 (Debian 14.8-1.pgdg120+1) --- Dumped by pg_dump version 15.3 (Ubuntu 15.3-0ubuntu0.23.04.1) +-- Dumped from database version 14.7 +-- Dumped by pg_dump version 15.4 (Ubuntu 15.4-0ubuntu0.23.04.1) SET statement_timeout = 0; SET lock_timeout = 0; @@ -76,6 +76,18 @@ CREATE TYPE public.familystatus AS ENUM ( ALTER TYPE public.familystatus OWNER TO navigator; +-- +-- Name: languagesource; Type: TYPE; Schema: public; Owner: navigator +-- + +CREATE TYPE public.languagesource AS ENUM ( + 'USER', + 'MODEL' +); + + +ALTER TYPE public.languagesource OWNER TO navigator; + SET default_tablespace = ''; SET default_table_access_method = heap; @@ -142,6 +154,43 @@ CREATE TABLE public.collection_organisation ( ALTER TABLE public.collection_organisation OWNER TO navigator; +-- +-- Name: entity_counter; Type: TABLE; Schema: public; Owner: navigator +-- + +CREATE TABLE public.entity_counter ( + id integer NOT NULL, + description character varying NOT NULL, + prefix character varying NOT NULL, + counter integer, + CONSTRAINT ck_entity_counter__prefix_allowed_orgs CHECK (((prefix)::text = ANY ((ARRAY['CCLW'::character varying, 'UNFCCC'::character varying])::text[]))) +); + + +ALTER TABLE public.entity_counter OWNER TO navigator; + +-- +-- Name: entity_counter_id_seq; Type: SEQUENCE; Schema: public; Owner: navigator +-- + +CREATE SEQUENCE public.entity_counter_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.entity_counter_id_seq OWNER TO navigator; + +-- +-- Name: entity_counter_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: navigator +-- + +ALTER SEQUENCE public.entity_counter_id_seq OWNED BY public.entity_counter.id; + + -- -- Name: family; Type: TABLE; Schema: public; Owner: navigator -- @@ -301,7 +350,7 @@ ALTER SEQUENCE public.geo_statistics_id_seq OWNED BY public.geo_statistics.id; CREATE TABLE public.geography ( id integer NOT NULL, - display_value text NOT NULL, + display_value text, value text, type text, parent_id integer, @@ -512,7 +561,9 @@ ALTER SEQUENCE public.physical_document_id_seq OWNED BY public.physical_document CREATE TABLE public.physical_document_language ( language_id integer NOT NULL, - document_id integer NOT NULL + document_id integer NOT NULL, + source public.languagesource DEFAULT 'MODEL'::public.languagesource NOT NULL, + visible boolean DEFAULT false NOT NULL ); @@ -544,6 +595,13 @@ CREATE TABLE public.variant ( ALTER TABLE public.variant OWNER TO navigator; +-- +-- Name: entity_counter id; Type: DEFAULT; Schema: public; Owner: navigator +-- + +ALTER TABLE ONLY public.entity_counter ALTER COLUMN id SET DEFAULT nextval('public.entity_counter_id_seq'::regclass); + + -- -- Name: geo_statistics id; Type: DEFAULT; Schema: public; Owner: navigator -- @@ -587,246 +645,19 @@ ALTER TABLE ONLY public.physical_document ALTER COLUMN id SET DEFAULT nextval('p -- --- Data for Name: alembic_version; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.alembic_version (version_num) FROM stdin; -0017 -\. - - --- --- Data for Name: app_user; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.app_user (email, name, hashed_password, is_superuser) FROM stdin; -\. - - --- --- Data for Name: collection; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.collection (import_id, title, description) FROM stdin; -\. - - --- --- Data for Name: collection_family; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.collection_family (collection_import_id, family_import_id) FROM stdin; -\. - - --- --- Data for Name: collection_organisation; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.collection_organisation (collection_import_id, organisation_id) FROM stdin; -\. - - --- --- Data for Name: family; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.family (title, import_id, description, geography_id, family_category) FROM stdin; -\. - - --- --- Data for Name: family_document; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.family_document (family_import_id, physical_document_id, import_id, variant_name, document_status, document_type, document_role) FROM stdin; -\. - - --- --- Data for Name: family_document_role; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.family_document_role (name, description) FROM stdin; -\. - - --- --- Data for Name: family_document_type; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.family_document_type (name, description) FROM stdin; -\. - - --- --- Data for Name: family_event; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.family_event (import_id, title, date, event_type_name, family_import_id, family_document_import_id, status) FROM stdin; -\. - - --- --- Data for Name: family_event_type; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.family_event_type (name, description) FROM stdin; -\. - - --- --- Data for Name: family_metadata; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.family_metadata (family_import_id, taxonomy_id, value) FROM stdin; -\. - - --- --- Data for Name: family_organisation; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.family_organisation (family_import_id, organisation_id) FROM stdin; -\. - - --- --- Data for Name: geo_statistics; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.geo_statistics (id, name, geography_id, legislative_process, federal, federal_details, political_groups, global_emissions_percent, climate_risk_index, worldbank_income_group, visibility_status) FROM stdin; -\. - - --- --- Data for Name: geography; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.geography (id, display_value, value, type, parent_id, slug) FROM stdin; -\. - - --- --- Data for Name: language; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.language (id, language_code, part1_code, part2_code, name) FROM stdin; -\. - - --- --- Data for Name: metadata_organisation; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.metadata_organisation (taxonomy_id, organisation_id) FROM stdin; -\. - - --- --- Data for Name: metadata_taxonomy; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.metadata_taxonomy (id, description, valid_metadata) FROM stdin; -\. - - --- --- Data for Name: organisation; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.organisation (id, name, description, organisation_type) FROM stdin; -\. - - --- --- Data for Name: organisation_admin; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.organisation_admin (appuser_email, organisation_id, job_title, is_active, is_admin) FROM stdin; -\. - - --- --- Data for Name: physical_document; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.physical_document (id, title, md5_sum, source_url, content_type, cdn_object) FROM stdin; -\. - - --- --- Data for Name: physical_document_language; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.physical_document_language (language_id, document_id) FROM stdin; -\. - - --- --- Data for Name: slug; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.slug (name, family_import_id, family_document_import_id) FROM stdin; -\. - - --- --- Data for Name: variant; Type: TABLE DATA; Schema: public; Owner: navigator --- - -COPY public.variant (variant_name, description) FROM stdin; -\. - - --- --- Name: geo_statistics_id_seq; Type: SEQUENCE SET; Schema: public; Owner: navigator --- - -SELECT pg_catalog.setval('public.geo_statistics_id_seq', 1, false); - - --- --- Name: geography_id_seq; Type: SEQUENCE SET; Schema: public; Owner: navigator --- - -SELECT pg_catalog.setval('public.geography_id_seq', 1, false); - - --- --- Name: language_id_seq; Type: SEQUENCE SET; Schema: public; Owner: navigator --- - -SELECT pg_catalog.setval('public.language_id_seq', 1, false); - - --- --- Name: metadata_taxonomy_id_seq; Type: SEQUENCE SET; Schema: public; Owner: navigator --- - -SELECT pg_catalog.setval('public.metadata_taxonomy_id_seq', 1, false); - - --- --- Name: organisation_id_seq; Type: SEQUENCE SET; Schema: public; Owner: navigator --- - -SELECT pg_catalog.setval('public.organisation_id_seq', 1, false); - - --- --- Name: physical_document_id_seq; Type: SEQUENCE SET; Schema: public; Owner: navigator +-- Name: alembic_version alembic_version_pkc; Type: CONSTRAINT; Schema: public; Owner: navigator -- -SELECT pg_catalog.setval('public.physical_document_id_seq', 1, false); +ALTER TABLE ONLY public.alembic_version + ADD CONSTRAINT alembic_version_pkc PRIMARY KEY (version_num); -- --- Name: alembic_version alembic_version_pkc; Type: CONSTRAINT; Schema: public; Owner: navigator +-- Name: geography ix_geography_slug; Type: CONSTRAINT; Schema: public; Owner: navigator -- -ALTER TABLE ONLY public.alembic_version - ADD CONSTRAINT alembic_version_pkc PRIMARY KEY (version_num); +ALTER TABLE ONLY public.geography + ADD CONSTRAINT ix_geography_slug UNIQUE (slug); -- @@ -861,6 +692,14 @@ ALTER TABLE ONLY public.collection_organisation ADD CONSTRAINT pk_collection_organisation PRIMARY KEY (collection_import_id); +-- +-- Name: entity_counter pk_entity_counter; Type: CONSTRAINT; Schema: public; Owner: navigator +-- + +ALTER TABLE ONLY public.entity_counter + ADD CONSTRAINT pk_entity_counter PRIMARY KEY (id); + + -- -- Name: family pk_family; Type: CONSTRAINT; Schema: public; Owner: navigator -- @@ -1013,6 +852,14 @@ ALTER TABLE ONLY public.variant ADD CONSTRAINT pk_variant PRIMARY KEY (variant_name); +-- +-- Name: entity_counter uq_entity_counter__prefix; Type: CONSTRAINT; Schema: public; Owner: navigator +-- + +ALTER TABLE ONLY public.entity_counter + ADD CONSTRAINT uq_entity_counter__prefix UNIQUE (prefix); + + -- -- Name: family_document uq_family_document__physical_document_id; Type: CONSTRAINT; Schema: public; Owner: navigator -- @@ -1045,13 +892,6 @@ ALTER TABLE ONLY public.language ADD CONSTRAINT uq_language__language_code UNIQUE (language_code); --- --- Name: ix_geography_slug; Type: INDEX; Schema: public; Owner: navigator --- - -CREATE UNIQUE INDEX ix_geography_slug ON public.geography USING btree (slug); - - -- -- Name: collection_family fk_collection_family__collection_import_id__collection; Type: FK CONSTRAINT; Schema: public; Owner: navigator -- @@ -1276,50 +1116,6 @@ REVOKE USAGE ON SCHEMA public FROM PUBLIC; GRANT ALL ON SCHEMA public TO PUBLIC; --- --- Name: entity_counter; Type: TABLE; Schema: public; Owner: navigator --- - -CREATE TABLE public.entity_counter ( - id integer NOT NULL, - description character varying NOT NULL, - prefix character varying NOT NULL, - counter integer, - CONSTRAINT ck_entity_counter__prefix_allowed_orgs CHECK (((prefix)::text = ANY ((ARRAY['CCLW'::character varying, 'UNFCCC'::character varying])::text[]))) -); - - -ALTER TABLE public.entity_counter OWNER TO navigator; - --- --- Name: entity_counter_id_seq; Type: SEQUENCE; Schema: public; Owner: navigator --- - -CREATE SEQUENCE public.entity_counter_id_seq - AS integer - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - -ALTER TABLE public.entity_counter_id_seq OWNER TO navigator; - --- --- Name: entity_counter_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: navigator --- - -ALTER SEQUENCE public.entity_counter_id_seq OWNED BY public.entity_counter.id; - - --- --- Name: entity_counter id; Type: DEFAULT; Schema: public; Owner: navigator --- - -ALTER TABLE ONLY public.entity_counter ALTER COLUMN id SET DEFAULT nextval('public.entity_counter_id_seq'::regclass); - - -- -- PostgreSQL database dump complete -- diff --git a/integration_tests/document/test_update.py b/integration_tests/document/test_update.py index b697fb9b..b9b11553 100644 --- a/integration_tests/document/test_update.py +++ b/integration_tests/document/test_update.py @@ -2,7 +2,11 @@ from fastapi.testclient import TestClient from fastapi import status from sqlalchemy.orm import Session -from app.clients.db.models.document.physical_document import PhysicalDocument +from app.clients.db.models.document.physical_document import ( + LanguageSource, + PhysicalDocument, + PhysicalDocumentLanguage, +) from app.clients.db.models.law_policy.family import FamilyDocument, Slug from app.model.document import DocumentWriteDTO @@ -53,6 +57,8 @@ def test_update_document(client: TestClient, test_db: Session, user_header_token assert data["type"] == "Annex" assert data["title"] == "Updated Title" assert data["source_url"] == "Updated Source" + assert data["slug"].startswith("updated-title") + assert data["user_language_name"] == "Ghotuo" fd, pd = _get_doc_tuple(test_db, "D.0.0.2") assert fd.import_id == "D.0.0.2" @@ -62,6 +68,15 @@ def test_update_document(client: TestClient, test_db: Session, user_header_token assert pd.title == "Updated Title" assert pd.source_url == "Updated Source" + # Check the user language in the db + lang = ( + test_db.query(PhysicalDocumentLanguage) + .filter(PhysicalDocumentLanguage.document_id == data["physical_id"]) + .filter(PhysicalDocumentLanguage.source == LanguageSource.USER) + .one() + ) + assert lang.language_id == 1 + # Check slug is updated too slugs = ( test_db.query(Slug).filter(Slug.family_document_import_id == "D.0.0.2").all() @@ -83,9 +98,18 @@ def test_update_document_idempotent( client: TestClient, test_db: Session, user_header_token ): setup_db(test_db) - document = EXPECTED_DOCUMENTS[1] + doc = EXPECTED_DOCUMENTS[1] + document = { + "variant_name": doc["variant_name"], + "role": doc["role"], + "type": doc["type"], + "title": doc["title"], + "source_url": doc["source_url"], + "user_language_name": doc["user_language_name"], + } + response = client.put( - f"/api/v1/documents/{document['import_id']}", + f"/api/v1/documents/{doc['import_id']}", json=document, headers=user_header_token, ) diff --git a/integration_tests/setup_db.py b/integration_tests/setup_db.py index 92851afa..6fad1775 100644 --- a/integration_tests/setup_db.py +++ b/integration_tests/setup_db.py @@ -2,7 +2,11 @@ from sqlalchemy.orm import Session from sqlalchemy import text from app.clients.db.models.app.users import Organisation -from app.clients.db.models.document.physical_document import PhysicalDocument +from app.clients.db.models.document.physical_document import ( + LanguageSource, + PhysicalDocument, + PhysicalDocumentLanguage, +) from app.clients.db.models.law_policy.collection import ( Collection, CollectionFamily, @@ -110,7 +114,8 @@ "cdn_object": "obj1", "source_url": "source1", "content_type": "application/pdf", - "user_language_name": "TODO", + "user_language_name": "English", + "calc_language_name": "Spanish", }, { "import_id": "D.0.0.2", @@ -126,7 +131,8 @@ "cdn_object": "obj2", "source_url": "source2", "content_type": "application/pdf", - "user_language_name": "TODO", + "user_language_name": None, + "calc_language_name": None, }, ] @@ -180,6 +186,10 @@ def setup_db(test_db: Session, configure_empty: bool = False): query = text(file.read()) test_db.execute(query) + setup_test_data(test_db, configure_empty) + + +def setup_test_data(test_db: Session, configure_empty: bool = False): org_id = _setup_organisation(test_db) _setup_family_data(test_db, org_id) @@ -322,6 +332,7 @@ def _setup_document_data( if configure_empty is True: return None + phys_docs = [] for index in range(EXPECTED_NUM_DOCUMENTS): data = EXPECTED_DOCUMENTS[index] pd = PhysicalDocument( @@ -334,6 +345,7 @@ def _setup_document_data( ) test_db.add(pd) test_db.flush() + phys_docs.append(pd.id) fd = FamilyDocument( family_import_id=family_id, @@ -347,6 +359,19 @@ def _setup_document_data( test_db.add(fd) test_db.flush() + # Setup english as user language for first document + test_db.add( + PhysicalDocumentLanguage( + language_id=1826, document_id=phys_docs[0], source=LanguageSource.USER + ) + ) + test_db.add( + PhysicalDocumentLanguage( + language_id=5991, document_id=phys_docs[0], source=LanguageSource.MODEL + ) + ) + test_db.flush() + def _setup_event_data( test_db: Session, diff --git a/unit_tests/helpers/document.py b/unit_tests/helpers/document.py index f82eedee..58074e5a 100644 --- a/unit_tests/helpers/document.py +++ b/unit_tests/helpers/document.py @@ -45,4 +45,5 @@ def create_document_read_dto( source_url="source", content_type="content_type", user_language_name="Ghotuo", + calc_language_name=None, )