def test_first_version_of_page_title_and_url_match(self):
        subtopic = SubtopicFactory()
        user = UserFactory(user_type=TypeOfUser.RDU_USER)
        created_measure_version = page_service.create_measure(
            subtopic=subtopic,
            measure_version_form=MeasureVersionForm(
                is_minor_update=False,
                title="the title",
                published_at=datetime.now().date()),
            created_by_email=user.email,
        )

        assert "the title" == created_measure_version.title
        assert "the-title" == created_measure_version.measure.slug

        updated_measure_version = page_service.update_measure_version(
            created_measure_version,
            measure_version_form=MeasureVersionForm(
                is_minor_update=True,
                title="an updated title",
                db_version_id=created_measure_version.db_version_id),
            data_source_forms=[],
            last_updated_by_email=user.email,
        )

        assert "an updated title" == updated_measure_version.title
        assert "an-updated-title" == updated_measure_version.measure.slug
def test_homepage_topics_display_in_rows_with_three_columns(
        number_of_topics, row_counts, test_app_client, logged_in_rdu_user):
    for i in range(number_of_topics):
        topic = TopicFactory(slug=f"topic-{i}",
                             title=f"Test topic page #{i}",
                             short_title=f"Testing #{i}")
        subtopic = SubtopicFactory(slug=f"subtopic-{i}",
                                   title=f"Test subtopic page #{i}",
                                   topic=topic)
        measure = MeasureFactory(slug=f"measure-{i}", subtopics=[subtopic])
        MeasureVersionFactory(status="APPROVED",
                              title=f"Test measure page #{i}",
                              version="1.0",
                              measure=measure)

    resp = test_app_client.get(url_for("static_site.index"))
    assert resp.status_code == 200

    page = BeautifulSoup(resp.data.decode("utf-8"), "html.parser")
    topic_rows = page.select(".topic-row")

    assert len(topic_rows) == len(row_counts)
    for i, topic_row in enumerate(topic_rows):
        assert len(topic_rows[i].select(".topic")) == row_counts[i]

    for i in range(number_of_topics):
        assert page.select(".topic a")[i].text.strip() == f"Testing #{i}"
def test_reorder_measures_triggers_build(test_app_client, logged_in_rdu_user):
    subtopic = SubtopicFactory()
    ids = [0, 1]
    reversed_ids = ids[::-1]
    for id_ in ids:
        MeasureVersionFactory(id=id_,
                              measure__position=id_,
                              measure__id=id_,
                              measure__subtopics=[subtopic],
                              measure__slug=str(id_))

    builds = Build.query.all()

    assert len(builds) == 0

    updates = []
    for position, id in enumerate(reversed_ids):
        updates.append({
            "position": position,
            "measure_id": str(id),
            "subtopic_id": subtopic.id
        })

    response = test_app_client.post(url_for("cms.set_measure_order"),
                                    data=json.dumps({"positions": updates}),
                                    content_type="application/json")

    assert response.status_code == 200

    builds = Build.query.all()

    assert len(builds) == 1
def test_reference_from_measure_to_subtopics():
    # Given a measure with no subtopic
    measure1 = MeasureFactory(subtopics=[])
    assert measure1.subtopics == []

    # When a measure is added to a subtopic
    subtopic = SubtopicFactory()
    subtopic.measures.append(measure1)

    # Then the measure has that subtopic in its subtopics list
    assert measure1.subtopics == [subtopic]
def test_topic_page_only_shows_empty_subtopics_if_user_can_create_a_measure(
        user_type, empty_subtopic_should_be_visible, test_app_client):
    user = UserFactory(user_type=user_type)
    SubtopicFactory(title="Test subtopic page", topic__slug="test-topic")

    with test_app_client.session_transaction() as session:
        session["user_id"] = user.id

    resp = test_app_client.get(
        url_for("static_site.topic", topic_slug="test-topic"))
    page = BeautifulSoup(resp.data.decode("utf-8"), "html.parser")

    assert resp.status_code == 200
    assert bool(page(string=re.compile(
        "Test subtopic page"))) is empty_subtopic_should_be_visible
    def test_create_page_trims_whitespace(self):
        subtopic = SubtopicFactory()
        user = UserFactory(user_type=TypeOfUser.RDU_USER)
        created_measure_version = page_service.create_measure(
            subtopic=subtopic,
            measure_version_form=MeasureVersionForm(
                is_minor_update=False,
                title="\n\t   I care\n",
                published_at=datetime.now().date(),
                methodology="\n\n\n\n\n\n",
            ),
            created_by_email=user.email,
        )

        assert created_measure_version.title == "I care"
        assert created_measure_version.methodology is None
    def test_draft_versions_of_page_after_first_title_can_be_changed_without_url_changing(
            self):
        subtopic = SubtopicFactory()
        user = UserFactory(user_type=TypeOfUser.RDU_USER)
        created_measure_version = page_service.create_measure(
            subtopic=subtopic,
            measure_version_form=MeasureVersionForm(
                is_minor_update=False,
                title="the title",
                published_at=datetime.now().date()),
            created_by_email=user.email,
        )

        assert "the title" == created_measure_version.title
        assert "the-title" == created_measure_version.measure.slug

        page_service.update_measure_version(
            created_measure_version,
            measure_version_form=MeasureVersionForm(
                is_minor_update=True,
                title="the title",
                status="APPROVED",
                db_version_id=created_measure_version.db_version_id,
            ),
            data_source_forms=[],
            last_updated_by_email=user.email,
        )

        copied_measure_version = page_service.create_measure_version(
            created_measure_version, NewVersionType.MINOR_UPDATE, user=user)

        assert "the title" == copied_measure_version.title
        assert "the-title" == copied_measure_version.measure.slug

        page_service.update_measure_version(
            copied_measure_version,
            measure_version_form=MeasureVersionForm(
                is_minor_update=True,
                title="the updated title",
                db_version_id=copied_measure_version.db_version_id),
            data_source_forms=[],
            last_updated_by_email=user.email,
        )

        assert "the updated title" == copied_measure_version.title
        assert "the-title" == copied_measure_version.measure.slug
    def test_measure_pages_have_csrf_protection(self, test_app_client,
                                                logged_in_rdu_user,
                                                stub_measure_data,
                                                isolated_app_config):
        LowestLevelOfGeographyFactory(
            name=stub_measure_data["lowest_level_of_geography_id"])
        subtopic = SubtopicFactory()
        current_app.config["WTF_CSRF_ENABLED"] = True
        res = test_app_client.get(
            url_for("cms.create_measure",
                    topic_slug=subtopic.topic.slug,
                    subtopic_slug=subtopic.slug),
            follow_redirects=True,
        )
        doc = html.fromstring(res.get_data(as_text=True))

        assert doc.xpath("//*[@id='csrf_token']")
def test_reference_from_subtopic_to_measures():
    # Given a subtopic with no measures
    subtopic = SubtopicFactory()
    assert subtopic.measures == []

    # When a subtopic is added to a measure
    measure1 = MeasureFactory(subtopics=[])
    measure1.subtopics.append(subtopic)

    # Then the subtopic has that measure in its measures list
    assert subtopic.measures == [measure1]

    # When another measure has the same subtopic
    measure2 = MeasureFactory(subtopics=[])
    measure2.subtopics.append(subtopic)

    # Then both measures are in the measures list
    assert subtopic.measures == [measure1, measure2]
    def test_create_measure_page(self, test_app_client, logged_in_rdu_user,
                                 stub_measure_data):
        LowestLevelOfGeographyFactory(
            name=stub_measure_data["lowest_level_of_geography_id"])
        subtopic = SubtopicFactory()
        form = MeasureVersionForm(is_minor_update=False, **stub_measure_data)

        response = test_app_client.post(
            url_for("cms.create_measure",
                    topic_slug=subtopic.topic.slug,
                    subtopic_slug=subtopic.slug),
            data=form.data,
            follow_redirects=True,
        )

        assert response.status_code == 200
        page = BeautifulSoup(response.data.decode("utf-8"), "html.parser")
        assert (page.find("div", class_="eff-flash-message__body").get_text(
            strip=True) == "Created page %s" % stub_measure_data["title"])
def test_adding_an_existing_data_source(driver, app, live_server):
    rdu_user = UserFactory(user_type=TypeOfUser.RDU_USER, active=True)

    topic = TopicFactory.create(title="Police and crime")
    subtopic = SubtopicFactory.create(title="Policing", topic=topic)
    DataSourceFactory.create(title="Police statistics 2019")

    existing_measure = MeasureFactory.create(subtopics=[subtopic])
    MeasureVersionFactory.create(status="APPROVED", measure=existing_measure)

    driver_login(driver, live_server, rdu_user)
    home_page = HomePage(driver, live_server)

    home_page.click_topic_link(topic)

    topic_page = TopicPage(driver, live_server, topic)
    topic_page.expand_accordion_for_subtopic(subtopic)

    topic_page.click_add_measure(subtopic)

    create_measure_page = MeasureEditPage(driver)
    create_measure_page.set_title("Arrests")
    create_measure_page.click_save()

    create_measure_page.click_add_primary_data_source()

    fill_in(driver,
            label_text="Search for an existing data source",
            with_text="Police statistics")
    click_button_with_text(driver, "Search")

    label_for_existing_data_source = driver.find_element_by_xpath(
        "//label[text()='Police statistics 2019']")

    label_for_existing_data_source.click()

    click_button_with_text(driver, "Select")

    assert "Successfully added the data source ‘Police statistics 2019’" in driver.page_source

    click_link_with_text(driver, "Preview this version")

    assert "Police statistics 2019" in driver.page_source
    def test_create_measure(self):
        subtopic = SubtopicFactory()
        user = UserFactory(user_type=TypeOfUser.RDU_USER)
        created_measure_version = page_service.create_measure(
            subtopic=subtopic,
            measure_version_form=MeasureVersionForm(
                is_minor_update=False,
                title="I care",
                published_at=datetime.now().date(),
                internal_reference="abc123"),
            created_by_email=user.email,
        )

        assert created_measure_version.title == "I care"
        assert created_measure_version.created_by == user.email
        # # TODO: remove this once MeasureVersions don't have reference
        assert created_measure_version.internal_reference == "abc123"

        created_measure = Measure.query.get(created_measure_version.measure_id)
        assert created_measure.slug == "i-care"
        assert created_measure.position == len(subtopic.measures) - 1
        assert created_measure.reference == "abc123"
def test_order_measures_in_subtopic(test_app_client, logged_in_rdu_user):
    subtopic = SubtopicFactory()
    ids = [0, 1, 2, 3, 4]
    for id_ in ids:
        MeasureVersionFactory(id=id_,
                              measure__position=id_,
                              measure__id=id_,
                              measure__subtopics=[subtopic],
                              measure__slug=str(id_))

    assert subtopic.measures[0].slug == "0"
    assert subtopic.measures[1].slug == "1"
    assert subtopic.measures[2].slug == "2"
    assert subtopic.measures[3].slug == "3"
    assert subtopic.measures[4].slug == "4"

    with test_app_client.session_transaction() as session:
        session["user_id"] = logged_in_rdu_user.id

    updates = []
    for position, id_ in enumerate(reversed(ids)):
        updates.append({
            "position": position,
            "measure_id": id_,
            "subtopic_id": subtopic.id
        })

    response = test_app_client.post(url_for("cms.set_measure_order"),
                                    data=json.dumps({"positions": updates}),
                                    content_type="application/json")

    assert response.status_code == 200

    assert subtopic.measures[0].slug == "4"
    assert subtopic.measures[1].slug == "3"
    assert subtopic.measures[2].slug == "2"
    assert subtopic.measures[3].slug == "1"
    assert subtopic.measures[4].slug == "0"
    def test_create_page_with_title_and_slug_already_exists_under_subtopic_raises_exception(
            self):
        subtopic = SubtopicFactory()
        user = UserFactory(user_type=TypeOfUser.RDU_USER)
        created_measure_version = page_service.create_measure(
            subtopic=subtopic,
            measure_version_form=MeasureVersionForm(
                is_minor_update=False,
                title="I care",
                published_at=datetime.now().date()),
            created_by_email=user.email,
        )

        with pytest.raises(PageExistsException):
            page_service.create_measure(
                subtopic=subtopic,
                measure_version_form=MeasureVersionForm(
                    is_minor_update=False,
                    title=created_measure_version.title,
                    published_at=created_measure_version.published_at,
                ),
                created_by_email=user.email,
            )
 def test_get_subtopic_finds_subtopic_by_slug(self):
     subtopic = SubtopicFactory(slug="subtopic-slug",
                                topic__slug="topic-slug")
     assert page_service.get_subtopic("topic-slug",
                                      "subtopic-slug") is subtopic
def test_version_history(test_app_client, logged_in_rdu_user):

    topic = TopicFactory(slug="my-topic")
    subtopic = SubtopicFactory(slug="my-subtopic", topic=topic)

    measure = MeasureFactory(slug="my-measure", subtopics=[subtopic])

    MeasureVersionFactory(
        measure=measure,
        status="APPROVED",
        version="1.0",
        published_at=datetime.datetime(2018, 1, 10),
        external_edit_summary="First published",
    )

    MeasureVersionFactory(
        measure=measure,
        status="APPROVED",
        version="1.1",
        published_at=datetime.datetime(2018, 2, 20),
        external_edit_summary="Fixed a spelling mistake.",
    )

    MeasureVersionFactory(
        measure=measure,
        status="APPROVED",
        version="1.2",
        published_at=datetime.datetime(2018, 12, 13),
        external_edit_summary="Updated headings for clarity.",
    )

    resp = test_app_client.get("/my-topic/my-subtopic/my-measure/latest")

    assert resp.status_code == 200

    page = BeautifulSoup(resp.data.decode("utf-8"), "html.parser")

    details_tag = details_tag_with_summary(page, "full page history")

    assert details_tag

    details_text = details_tag.get_text(separator="\n", strip=True).split("\n")

    assert details_text == [
        "full page history",
        "13 December 2018",
        "Updated headings for clarity.",
        "20 February 2018",
        "Fixed a spelling mistake.",
        "10 January 2018",
        "First published",
    ]

    first_published_link = find_link_with_text(details_tag, "10 January 2018")

    assert first_published_link
    assert first_published_link.get(
        "href") == "/my-topic/my-subtopic/my-measure/1.0"

    spelling_mistake_link = find_link_with_text(details_tag,
                                                "20 February 2018")

    assert spelling_mistake_link
    assert spelling_mistake_link.get(
        "href") == "/my-topic/my-subtopic/my-measure/1.1"

    updated_headings_link = find_link_with_text(details_tag,
                                                "13 December 2018")

    assert updated_headings_link
    assert updated_headings_link.get(
        "href") == "/my-topic/my-subtopic/my-measure/1.2"
 def test_get_subtopic_raises_if_wrong_topic_slug(self):
     SubtopicFactory(slug="subtopic-slug", topic__slug="topic-slug")
     with pytest.raises(PageNotFoundException):
         page_service.get_subtopic("not-the-right-topic", "subtopic-slug")
def test_references_between_subtopic_and_topic():
    topic = TopicFactory()
    subtopic = SubtopicFactory(topic=topic)

    assert topic.subtopics == [subtopic]
    assert subtopic.topic == topic