Ejemplo n.º 1
0
    def get_updated_content_and_parent(update_field):
        """Run update_content_from_s3_data with test data and return content, parent"""
        website = WebsiteFactory.build()
        content = WebsiteContentFactory.build(
            markdown="original markdown",
            metadata={"title": "original title"},
            website=website,
        )
        content.save = Mock()
        # prepare the parent, but do not set content.parent_id.
        # that's one of the things we'll test
        parent = WebsiteContentFactory.build(id=123)

        s3_content_data = {
            "markdown": "s3 markdown",
            "metadata": {
                "title": "s3 title",
                "author": "s3 author",
                "parent_uid": "s3_parent_uid",
            },
            "parent": parent,
        }
        with patch("websites.models.WebsiteContent.objects") as mock:
            mock.filter.return_value.first.return_value = content
            website = content.website
            text_id = content.text_id
            update_content_from_s3_data(website, text_id, s3_content_data,
                                        update_field)

        return content, parent
Ejemplo n.º 2
0
def test_baseurl_replacer_handle_specific_url_replacements(
    url, content_relative_dirpath, filename
):
    """
    Test specific replacements

    This test could perhaps be dropped. It was written before ContentLookup was
    moved to a separate module, and the functionality is tested their, now, too.
    """
    website_uuid = "website-uuid"
    website = WebsiteFactory.build(uuid=website_uuid)
    markdown = f"my [pets]({{{{< baseurl >}}}}{url}) are legion"
    expected_markdown = 'my {{% resource_link content-uuid "pets" %}} are legion'
    target_content = WebsiteContentFactory.build(markdown=markdown, website=website)

    linkable = WebsiteContentFactory.build(
        website=website,
        dirpath=f"content{content_relative_dirpath}",
        filename=filename,
        text_id="content-uuid",
    )

    cleaner = get_markdown_cleaner([linkable])
    cleaner.update_website_content(target_content)

    assert target_content.markdown == expected_markdown
Ejemplo n.º 3
0
def test_baseurl_replacer_replaces_content_in_same_course(
    website_uuid, should_markdown_change
):
    """
    Double check that if the dirpath + filename match multiple times, the
    content chosen is from the same course as the markdown being edited
    """

    markdown = R"""
    Kittens [meow]({{< baseurl >}}/resources/pets/cat) meow.
    """
    w1 = WebsiteFactory.build(uuid="website-uuid-111")
    w2 = WebsiteFactory.build(uuid="website-uuid-222")
    websites = {w.uuid: w for w in [w1, w2]}
    target_content = WebsiteContentFactory.build(markdown=markdown, website=w1)

    linkable = WebsiteContentFactory.build(
        website=websites[website_uuid],
        dirpath="content/resources/pets",
        filename="cat",
        text_id="uuid-111",
    )

    cleaner = get_markdown_cleaner([linkable])
    cleaner.update_website_content(target_content)

    is_markdown_changed = target_content.markdown != markdown
    assert is_markdown_changed == should_markdown_change
Ejemplo n.º 4
0
def test_resolveuid_conversion_within_same_site(markdown, expected):
    """Check shortcodes are used within same site."""
    website = WebsiteFactory.build()
    target_content = WebsiteContentFactory.build(markdown=markdown, website=website)
    linked_content = WebsiteContentFactory.build(
        text_id="5cf754b2-b97b-4ac1-8dab-deed1201de94", website=website
    )

    cleaner = get_markdown_cleaner([target_content, linked_content])
    cleaner.update_website_content(target_content)

    assert target_content.markdown == expected
Ejemplo n.º 5
0
def test_updates_multiple_metadata_fields():
    """
    Check that a single call to update_website_content modifies multiple fields
    for rules that have multiple fields associated.
    """
    assert len(MetadataRelativeUrlsFix.fields) > 1

    website = WebsiteFactory.build(name="site-1")
    wc1 = WebsiteContentFactory.build(
        filename="thing1",
        dirpath="content/resources",
        website=website,
    )
    wc2 = WebsiteContentFactory.build(filename="thing2",
                                      dirpath="content/pages/two",
                                      website=website)

    content_to_clean = WebsiteContentFactory.build(
        metadata={
            "related_resources_text": """Hello
                Change this: [to thing1](resources/thing1#fragment "And a title!") cool'
                
                Leave this alone: [wiki](https://wikipedia.org) same

                And this [course link](/courses/8-02/pages/jigawatts)
            """,
            "image_metadata": {
                "caption": "And now [thing2](pages/two/thing2)"
            },
        },
        website=website,
    )

    cleaner = get_markdown_cleaner([wc1, wc2])
    cleaner.update_website_content(content_to_clean)

    expected_related_resources = """Hello
                Change this: [to thing1](/courses/site-1/resources/thing1#fragment) cool'
                
                Leave this alone: [wiki](https://wikipedia.org) same

                And this [course link](/courses/8-02/pages/jigawatts)
            """
    expected_caption = "And now [thing2](/courses/site-1/pages/two/thing2)"
    assert (content_to_clean.metadata["related_resources_text"] ==
            expected_related_resources)
    assert content_to_clean.metadata["image_metadata"][
        "caption"] == expected_caption
Ejemplo n.º 6
0
def test_get_destination_filepath_errors(mocker, has_missing_name,
                                         is_bad_config_item):
    """
    get_destination_filepath should log an error and return None if the site config is missing the given name, or if
    the config item does not have a properly configured destination.
    """
    patched_log = mocker.patch("content_sync.utils.log")
    # From basic-site-config.yml
    config_item_name = "blog"
    if is_bad_config_item:
        mocker.patch.object(
            SiteConfig,
            "find_item_by_name",
            return_value=ConfigItem(item={
                "name": config_item_name,
                "poorly": "configured"
            }),
        )
    starter = WebsiteStarterFactory.build()
    content = WebsiteContentFactory.build(
        is_page_content=False,
        type="non-existent-config-name"
        if has_missing_name else config_item_name,
    )
    return_value = get_destination_filepath(content=content,
                                            site_config=SiteConfig(
                                                starter.config))
    patched_log.error.assert_called_once()
    assert return_value is None
Ejemplo n.º 7
0
def test_resolveuid_conversion_cross_site(markdown, expected):
    """Check shortcodes are used within same site."""
    target_content = WebsiteContentFactory.build(
        markdown=markdown, website=WebsiteFactory.build()
    )
    linked_content = WebsiteContentFactory.build(
        text_id="5cf754b2-b97b-4ac1-8dab-deed1201de94",
        dirpath="content/pages/path/to",
        filename="thing",
        website=WebsiteFactory.build(name="other-site-name"),
    )

    cleaner = get_markdown_cleaner([target_content, linked_content])
    cleaner.update_website_content(target_content)

    assert target_content.markdown == expected
Ejemplo n.º 8
0
def test_hugo_menu_yaml_serialize(omnibus_config):
    """HugoMenuYamlFileSerializer.serialize should create the expected file contents"""
    nav_menu_config_item = omnibus_config.find_item_by_name("navmenu")
    assert nav_menu_config_item is not None
    # Create page object referred to in the menu data
    WebsiteContentFactory.create(
        text_id=EXAMPLE_UUIDS[0],
        is_page_content=True,
        dirpath="path/to",
        filename="myfile",
    )
    example_menu_data = get_example_menu_data()
    content = WebsiteContentFactory.build(
        is_page_content=False,
        type=nav_menu_config_item.name,
        metadata={"mainmenu": example_menu_data},
    )
    serialized_data = HugoMenuYamlFileSerializer(omnibus_config).serialize(content)
    parsed_serialized_data = yaml.load(serialized_data, Loader=yaml.SafeLoader)
    assert parsed_serialized_data == {
        "mainmenu": [
            {**example_menu_data[0], "url": "/path/to/myfile"},
            example_menu_data[1],
        ]
    }
Ejemplo n.º 9
0
def test_legacy_shortcode_fix_one(markdown, expected_markdown):
    """Test specific replacements"""
    website = WebsiteFactory.build()
    target_content = WebsiteContentFactory.build(markdown=markdown, website=website)

    cleaner = Cleaner(LegacyShortcodeFixOne())
    cleaner.update_website_content(target_content)
    assert target_content.markdown == expected_markdown
Ejemplo n.º 10
0
def test_content_finder_returns_metadata_for_site(site_uuid, content_index):
    contents = [
        WebsiteContentFactory.build(
            website=WebsiteFactory.build(uuid="website_one"),
            type="sitemetadata",
            text_id="content-1",
        ),
        WebsiteContentFactory.build(
            website=WebsiteFactory.build(uuid="website_two"),
            type="sitemetadata",
            text_id="content-2",
        ),
    ]
    with patch_website_contents_all(contents):
        content_lookup = ContentLookup()
        assert (content_lookup.find_within_site(
            site_uuid, "/") == contents[content_index])
Ejemplo n.º 11
0
def test_rootrel_rule_only_uses_resource_lines_for_same_site(
        markdown, site_name, expected_markdown):
    w1 = WebsiteFactory.build(name="site_one")
    w2 = WebsiteFactory.build(name="site_two")
    websites = {w.name: w for w in [w1, w2]}
    c1 = WebsiteContentFactory.build(website=w1,
                                     filename="page1",
                                     dirpath="content/pages/stuff",
                                     text_id="uuid-1")

    content_to_clean = WebsiteContentFactory.build(website=websites[site_name],
                                                   markdown=markdown)

    cleaner = get_markdown_cleaner([w1], [c1])
    cleaner.update_website_content(content_to_clean)

    assert content_to_clean.markdown == expected_markdown
Ejemplo n.º 12
0
def test_legacy_file_lookup_raises_nonunique_for_multiple_matches():
    c1a = WebsiteContentFactory.build(
        website_id="site-uuid-one",
        file=f"/courses/site_one/{string_uuid()}_some_file_name.jpg",
        text_id="content-uuid-1",
    )
    c1b = WebsiteContentFactory.build(
        website_id="site-uuid-one",
        file=f"/courses/site_one/{string_uuid()}_some_file_name.jpg",
        text_id="content-uuid-2",
    )
    contents = [c1a, c1b]
    with patch_website_contents_all(contents):
        legacy_file_lookup = LegacyFileLookup()
        with pytest.raises(legacy_file_lookup.MultipleMatchError):
            assert legacy_file_lookup.find("site-uuid-one",
                                           "some_file_name.jpg")
Ejemplo n.º 13
0
def test_rootrel_rule_handles_site_homeages_correctly(markdown, site_name,
                                                      expected_markdown):
    w1 = WebsiteFactory.build(name="site_one")
    w2 = WebsiteFactory.build(name="site_two")
    websites = {w.name: w for w in [w1, w2]}
    c1 = WebsiteContentFactory.build(website=w1,
                                     type="sitemetadata",
                                     filename="",
                                     dirpath="",
                                     text_id="uuid-1")
    content_to_clean = WebsiteContentFactory.build(website=websites[site_name],
                                                   markdown=markdown)

    cleaner = get_markdown_cleaner([w1], [c1])
    cleaner.update_website_content(content_to_clean)

    assert content_to_clean.markdown == expected_markdown
Ejemplo n.º 14
0
def test_baseurl_replacer_specific_title_replacements(markdown, expected_markdown):
    """Test specific replacements"""
    website_uuid = "website-uuid"
    website = WebsiteFactory.build(uuid=website_uuid)
    target_content = WebsiteContentFactory.build(markdown=markdown, website=website)

    linkable = WebsiteContentFactory.build(
        website=website,
        dirpath="content/resources/path/to",
        filename="file1",
        text_id="content-uuid-1",
    )

    cleaner = get_markdown_cleaner([linkable])
    cleaner.update_website_content(target_content)

    assert target_content.markdown == expected_markdown
Ejemplo n.º 15
0
def test_shortcode_standardizer(text, expected):
    """Check that it removes extra args from resource shortcodes"""
    target_content = WebsiteContentFactory.build(
        markdown=text, website=WebsiteFactory.build())

    cleaner = get_markdown_cleaner()
    cleaner.update_website_content(target_content)

    assert target_content.markdown == expected
Ejemplo n.º 16
0
def test_websitecontent_full_metadata(has_file_widget, has_file):
    """WebsiteContent.full_metadata returns expected file field in metadata when appropriate"""
    file = SimpleUploadedFile("test.txt", b"content")
    title = ("Test Title", )
    description = "Test Description"
    config_fields = [
        {
            "label": "Description",
            "name": "description",
            "widget": "text"
        },
        {
            "label": "My File",
            "name": "my_file",
            "widget": "file",
            "required": False
        },
    ]
    site_config = {
        "content-dir":
        "content",
        "collections": [{
            "name":
            "resource",
            "label":
            "Resource",
            "category":
            "Content",
            "folder":
            "content/resource",
            "fields":
            config_fields if has_file_widget else config_fields[0:1],
        }],
    }
    starter = WebsiteStarterFactory.create(config=site_config)
    content = WebsiteContentFactory.build(
        type="resource",
        metadata={
            "title": title,
            "description": description
        },
        file=(file if has_file else None),
        website=WebsiteFactory(starter=starter),
    )

    if has_file_widget:
        assert content.full_metadata == {
            "title": title,
            "description": description,
            "my_file": content.file.url if has_file else None,
        }
    else:
        assert content.full_metadata == {
            "title": title,
            "description": description
        }
Ejemplo n.º 17
0
def test_resolveuid_leaves_stuff_alone_if_it_should(markdown, expected):
    """Check shortcodes are used within same site."""
    target_content = WebsiteContentFactory.build(
        markdown=markdown, website=WebsiteFactory.build()
    )

    cleaner = get_markdown_cleaner([target_content])
    cleaner.update_website_content(target_content)

    assert target_content.markdown == expected
Ejemplo n.º 18
0
def test_factory_for_content_hugo_markdown():
    """
    ContentFileSerializerFactory.for_content should return the Hugo markdown serializer if the content object
    is page content.
    """
    content = WebsiteContentFactory.build(is_page_content=True)
    site_config = SiteConfig(content.website.starter.config)
    assert isinstance(
        ContentFileSerializerFactory.for_content(site_config, content),
        HugoMarkdownFileSerializer,
    )
Ejemplo n.º 19
0
def test_baseurl_replacer_handles_index_files():
    """Test specific replacements"""
    website_uuid = "website-uuid"
    website = WebsiteFactory.build(uuid=website_uuid)
    markdown = R"my [pets]({{< baseurl >}}/pages/cute/pets) are legion"
    expected_markdown = R'my {{% resource_link content-uuid "pets" %}} are legion'
    target_content = WebsiteContentFactory.build(markdown=markdown, website=website)

    linkable = WebsiteContentFactory.build(
        website=website,
        dirpath="content/pages/cute/pets",
        filename="_index",
        text_id="content-uuid",
    )

    cleaner = get_markdown_cleaner([linkable])
    cleaner.update_website_content(target_content)

    assert linkable.filename not in target_content.markdown
    assert target_content.markdown == expected_markdown
Ejemplo n.º 20
0
def test_get_rootrelative_url_from_content():
    c1 = WebsiteContentFactory.build(
        website=WebsiteFactory.build(name="site-name-1"),
        dirpath="content/pages/path/to",
        filename="file1",
    )
    c2 = WebsiteContentFactory.build(
        website=WebsiteFactory.build(name="site-name-2"),
        dirpath="content/pages/assignments",
        filename="_index",
    )
    c3 = WebsiteContentFactory.build(
        website=WebsiteFactory.build(name="site-THREE"),
        dirpath="content/resources/long/path/to",
        filename="file3",
    )
    urls = [get_rootrelative_url_from_content(c) for c in [c1, c2, c3]]

    assert urls[0] == "/courses/site-name-1/pages/path/to/file1"
    assert urls[1] == "/courses/site-name-2/pages/assignments"
    assert urls[2] == "/courses/site-THREE/resources/long/path/to/file3"
Ejemplo n.º 21
0
def test_rootrel_rule_uses_images_for_image(markdown, site_name,
                                            expected_markdown):
    w1 = WebsiteFactory.build(name="site_one")
    w2 = WebsiteFactory.build(name="site_two")
    websites = {w.name: w for w in [w1, w2]}
    c1 = WebsiteContentFactory.build(
        website=w1,
        text_id="uuid-1",
        file=
        f"only/last/part/matters/for/now/{string_uuid()}_old_image_filename123.jpg",
        # in general the new filename is the same as old,
        # possibly appended with "-1" or "-2" if there were duplicates
        filename="new_image_filename123.jpg",
        dirpath="content/resources",
    )
    content_to_clean = WebsiteContentFactory.build(website=websites[site_name],
                                                   markdown=markdown)
    cleaner = get_markdown_cleaner([w1], [c1])
    cleaner.update_website_content(content_to_clean)

    assert content_to_clean.markdown == expected_markdown
Ejemplo n.º 22
0
def test_legacy_file_lookup(site_uuid, filename, expected_index):
    c1a = WebsiteContentFactory.build(
        website_id="site-uuid-one",
        file=f"/courses/site_one/{string_uuid()}_someFileName.jpg",
        text_id="content-uuid-1a",
    )
    c1b = WebsiteContentFactory.build(
        website_id="site-uuid-one",
        file=f"/courses/site_one/{string_uuid()}_somefilename.jpg",
        text_id="content-uuid-1b",
    )
    c2 = WebsiteContentFactory.build(
        website_id="site-uuid-two",
        file=f"/courses/site_two/{string_uuid()}_someFileName.jpg",
        text_id="content-uuid-two",
    )
    contents = [c1a, c1b, c2]
    expected = contents[expected_index]
    with patch_website_contents_all(contents):
        legacy_file_lookup = LegacyFileLookup()
        assert legacy_file_lookup.find(site_uuid, filename) == expected
Ejemplo n.º 23
0
def test_websitecontent_calculate_checksum(metadata, markdown, dirpath,
                                           exp_checksum):
    """ Verify calculate_checksum() returns the expected sha256 checksum """
    content = WebsiteContentFactory.build(
        markdown=markdown,
        metadata=metadata,
        dirpath=dirpath,
        filename="myfile",
        type="mytype",
        title="My Title",
    )
    # manually computed checksum in a python shell
    assert content.calculate_checksum() == exp_checksum
Ejemplo n.º 24
0
def test_content_finder_is_site_specific():
    """Test that ContentLookup is site specific"""
    content_w1 = WebsiteContentFactory.build(
        website=WebsiteFactory.build(uuid="website-uuid-1"),
        dirpath="content/resources/path/to",
        filename="file1",
        text_id="content-uuid-1",
    )
    content_w2 = WebsiteContentFactory.build(
        website=WebsiteFactory.build(uuid="website-uuid-2"),
        dirpath="content/resources/path/to",
        filename="file1",
        text_id="content-uuid-1",
    )

    with patch_website_contents_all([content_w1, content_w2]):
        content_lookup = ContentLookup()

        url = "/resources/path/to/file1"
        assert content_lookup.find_within_site(content_w1.website_id,
                                               url) == content_w1
        assert content_lookup.find_within_site(content_w2.website_id,
                                               url) == content_w2
Ejemplo n.º 25
0
def test_content_finder_specific_url_replacements(url,
                                                  content_relative_dirpath,
                                                  filename):
    content = WebsiteContentFactory.build(
        website=WebsiteFactory.build(uuid="website_uuid"),
        dirpath=f"content{content_relative_dirpath}",
        filename=filename,
        text_id="content-uuid",
    )

    with patch_website_contents_all([content]):
        content_lookup = ContentLookup()

        assert content_lookup.find_within_site("website_uuid", url) == content
Ejemplo n.º 26
0
def test_factory_for_content_hugo_menu(omnibus_config):
    """
    ContentFileSerializerFactory.for_content should return the Hugo menu serializer class if the content is
    associated with a config item that has "menu" fields
    """
    nav_menu_config_item = omnibus_config.find_item_by_name("navmenu")
    assert nav_menu_config_item is not None
    content = WebsiteContentFactory.build(
        is_page_content=False, type=nav_menu_config_item.name
    )
    assert isinstance(
        ContentFileSerializerFactory.for_content(
            site_config=omnibus_config, website_content=content
        ),
        HugoMenuYamlFileSerializer,
    )
Ejemplo n.º 27
0
def test_shortcode_standardizer():
    """Check that it replaces resource_file links as expected"""
    markdown = R"""
    Roar {{< cat uuid    "some \"text\" cool">}}

    {{< dog a     b >}}

    Hello world {{< wolf "a     b" >}}
    """
    target_content = WebsiteContentFactory.build(
        markdown=markdown, website=WebsiteFactory.build())

    cleaner = get_markdown_cleaner()
    cleaner.update_website_content(target_content)

    assert target_content.markdown == markdown
Ejemplo n.º 28
0
def test_get_destination_url_errors(mocker):
    """
    get_destination_url should log an error if it is called with a a WebsiteContent object without
    is_page_content set to true
    """
    patched_log = mocker.patch("content_sync.utils.log")
    # From basic-site-config.yml
    config_item_name = "blog"
    starter = WebsiteStarterFactory.build()
    content = WebsiteContentFactory.build(
        is_page_content=False,
        type=config_item_name,
    )
    return_value = get_destination_url(content=content,
                                       site_config=SiteConfig(starter.config))
    patched_log.error.assert_called_once()
    assert return_value is None
Ejemplo n.º 29
0
def test_serialize_content_to_file(mocker):
    """serialize_content_to_file should pick the correct serializer class and serialize a website content object"""
    mock_serializer = mocker.MagicMock(spec=BaseContentFileSerializer)
    patched_serializer_factory = mocker.patch(
        "content_sync.serializers.ContentFileSerializerFactory", autospec=True
    )
    patched_serializer_factory.for_content.return_value = mock_serializer
    website_content = WebsiteContentFactory.build()
    site_config = SiteConfig(website_content.website.starter.config)
    serialized = serialize_content_to_file(
        site_config=site_config, website_content=website_content
    )

    patched_serializer_factory.for_content.assert_called_once_with(
        site_config, website_content
    )
    mock_serializer.serialize.assert_called_once_with(website_content=website_content)
    assert serialized == mock_serializer.serialize.return_value
Ejemplo n.º 30
0
def test_factory_for_content_data(file_value, exp_serializer_cls):
    """
    ContentFileSerializerFactory.for_content should return the correct data file serializer when given a content object
    that was created for a "file"-type config item.
    """
    content = WebsiteContentFactory.build(is_page_content=False, type="sometype")
    site_config = SiteConfig(content.website.starter.config)
    # Create a new "file"-type config item which will match our website content object
    raw_files_item = next(
        raw_config_item
        for raw_config_item in site_config.raw_data["collections"]
        if "files" in raw_config_item
    )
    new_files_item = raw_files_item.copy()
    new_files_item["name"] = "newfiles"
    new_files_item["files"] = [
        {**raw_files_item["files"][0].copy(), "name": content.type, "file": file_value}
    ]
    site_config.raw_data["collections"].append(new_files_item)

    assert isinstance(
        ContentFileSerializerFactory.for_content(site_config, content),
        exp_serializer_cls,
    )