Esempio n. 1
0
 def clean_config(self):
     """Ensures that the site config value obeys our schema"""
     config = self.cleaned_data["config"]
     try:
         validate_parsed_site_config(config)
     except ValueError as ex:
         raise ValidationError(str(ex)) from ex
     return config
Esempio n. 2
0
def test_validate_parsed_site_config(mocker):
    """validate_parsed_site_config should dump a parsed site config as YAML and validate it"""
    patched_validate_raw = mocker.patch(
        "websites.config_schema.api.validate_raw_site_config")
    parsed_config = {"parsed": "config"}
    raw_config = yaml.dump(parsed_config, Dumper=yaml.Dumper)
    validate_parsed_site_config(parsed_config)
    patched_validate_raw.assert_called_once_with(raw_config)
Esempio n. 3
0
def test_folders_content_only(parsed_site_config):
    """'folder'-type config items must point to the content directory"""
    config = parsed_site_config.copy()
    config["collections"][0] = {
        **config["collections"][0],
        "folder": "not-the-content-folder",
    }
    with pytest.raises(ValueError):
        validate_parsed_site_config(config)
Esempio n. 4
0
def test_exclusive_collection_keys(parsed_site_config):
    """A collection item defining more than one of a set of mutually-exclusive keys should cause a validation error"""
    config = parsed_site_config.copy()
    config["collections"][0] = {
        **config["collections"][0],
        "folder": "folder1",
        "files": [],
    }
    with pytest.raises(ValueError):
        validate_parsed_site_config(config)
Esempio n. 5
0
def test_required_title_rule(parsed_site_config, attr, value):
    """If a config item includes a "title" field, it should be set to required and have the correct type"""
    config = parsed_site_config.copy()
    config["collections"][0] = {
        **config["collections"][0],
        "fields": [{
            **VALID_TITLE_FIELD, attr: value
        }],
    }
    with pytest.raises(ValueError):
        validate_parsed_site_config(config)
Esempio n. 6
0
def test_valid_local_dev_configs():
    """All site configs defined in the local override should be valid"""
    total_example_configs = 0
    for dirpath, base_filename, extension in example_config_file_iter():
        with open(os.path.join(dirpath, f"{base_filename}.{extension}")) as f:
            raw_config_override = f.read().strip()
        parsed_site_config = yaml.load(raw_config_override,
                                       Loader=yaml.SafeLoader)
        validate_parsed_site_config(parsed_site_config)
        total_example_configs += 1
    assert total_example_configs >= 1
Esempio n. 7
0
def test_menu_rule(parsed_site_config):
    """If a config item includes a "menu" widget field, it should not have any other fields with other widget types"""
    config = parsed_site_config.copy()
    menu_field = {"name": "menu1", "label": "Menu 1", "widget": "menu"}
    # One "menu"-widget field and one non-"menu"-widget field
    config["collections"][0] = {
        **config["collections"][0],
        "fields":
        config["collections"][0]["fields"] + [menu_field],
    }
    with pytest.raises(ValueError):
        validate_parsed_site_config(config)
    # Two "menu"-widget fields
    config["collections"][0]["fields"] = [
        menu_field, {
            **menu_field, "name": "menu2"
        }
    ]
    validate_parsed_site_config(config)
Esempio n. 8
0
    def handle(self, *args, **options):
        config_paths = options["config_path"]
        slugs_to_override = options["starter"]
        if len(config_paths) > len(self._get_config_paths()):
            config_paths = config_paths[len(self._get_config_paths()) :]
        if len(slugs_to_override) > len(self._get_slugs()):
            slugs_to_override = slugs_to_override[len(self._get_slugs()) :]
        if len(config_paths) != len(slugs_to_override):
            raise CommandError(
                "Need to provide the same number of config paths and starter slugs to override "
                f"({len(config_paths)} != {len(slugs_to_override)})"
            )

        for config_path, starter_slug in zip(config_paths, slugs_to_override):
            with open(os.path.join(settings.BASE_DIR, config_path)) as f:
                raw_config = f.read().strip()
            parsed_config = yaml.load(raw_config, Loader=yaml.SafeLoader)
            try:
                starter = WebsiteStarter.objects.get(slug=starter_slug)
            except WebsiteStarter.DoesNotExist:
                self.stdout.write(
                    self.style.ERROR(
                        f"WebsiteStarter with slug '{starter_slug}' not found"
                    )
                )
                continue

            if starter.config != parsed_config:
                validate_parsed_site_config(parsed_config)
                starter.config = parsed_config
                starter.save()
                self.stdout.write(
                    self.style.SUCCESS(f"Config updated for '{starter_slug}' starter.")
                )
            else:
                self.stdout.write(
                    self.style.WARNING(
                        f"No config changes detected for '{starter_slug}' starter."
                    )
                )
Esempio n. 9
0
def test_unique_names(parsed_site_config):
    """Every config item in a site config should have a unique name"""
    config = parsed_site_config.copy()
    config["collections"][1] = {
        **config["collections"][1],
        "name": config["collections"][0]["name"],
    }
    with pytest.raises(ValueError):
        validate_parsed_site_config(config)
    config = parsed_site_config.copy()
    # Find then index of a config item that defines a "files" list
    file_config_idx = next(
        i for i, config_item in enumerate(config["collections"])
        if "files" in config_item)
    # Set a "file" config item to have the same name as a top-level config item
    config["collections"][file_config_idx]["files"][0] = {
        **config["collections"][file_config_idx]["files"][0],
        "name":
        config["collections"][0]["name"],
    }
    with pytest.raises(ValueError):
        validate_parsed_site_config(config)
Esempio n. 10
0
def test_invalid_key(parsed_site_config):
    """An invalid top-level key should cause a validation error"""
    config = parsed_site_config.copy()
    config["invalid_key"] = [1, 2, 3]
    with pytest.raises(ValueError):
        validate_parsed_site_config(config)