def test_minor_edit(action, make_one_page_config, tmp_path, setup_page): """Tests that minor edit action is recorded on the page. API does not allow creation of the page to be a minor edit, only an update""" if action == "create": config_file, config = make_one_page_config result = run_with_config(config_file=config_file, pre_args=["--minor-edit"], input="Y\nN\nY\n") page_id = get_page_id_from_stdout(result.stdout) else: overwrite_file, new_text, overwrite_config = mk_fake_file( tmp_path, filename="overwrite") config_file, (page_id, page_title) = setup_page(1) result = run_with_config( config_file=overwrite_config, pre_args=["--page-title", page_title, "--minor-edit"], ) assert result.exit_code == 0 last_update = confluence_instance.get_content_history(page_id).get( "lastUpdated") if action == "create": assert not last_update.get( "minorEdit"), "Creation was marked as minor edit" else: # Looks like Atlassian stopped exposing this in the API :( no notifications are sent out though with pytest.raises(AssertionError): assert last_update.get( "minorEdit"), "Page update was not marked as minor edit"
def test_multiple_pages_with_comment(apply_config_answer, tmp_path): config_file, config = generate_local_config(tmp_path=tmp_path, pages=2) # create the pages result = run_with_config( config_file=config_file, input=f"{apply_config_answer}\n" "Y\n" # create first page "N\n" # do not look for parent "Y\n" # create in root "Y\n" # create second page "N\n" "Y\n", other_args=["create_comment"], ) assert result.exit_code == 0 for page in config.pages: # Regenerate content of page mk_fake_file(tmp_path, filename=page.page_title.lower().replace(" ", "_")) result = run_with_config( config_file=config_file, input=f"{apply_config_answer}\n" "Y\n" # create first page "N\n" # do not look for parent "Y\n" # create in root "Y\n" # create second page "N\n" "Y\n", other_args=["update_comment"], ) assert result.exit_code == 0 if apply_config_answer in {"A", ""}: for page in config.pages: assert (_get_version_comment( page_title=page.page_title, space=page.page_space, confluence=confluence_instance, ) == "update_comment") elif apply_config_answer == "F": for page in config.pages: if page == config.pages[0]: _checked_comment = "update_comment" else: _checked_comment = "" assert (_get_version_comment( page_title=page.page_title, space=page.page_space, confluence=confluence_instance, ) == _checked_comment) elif apply_config_answer == "N": for page in config.pages: assert (_get_version_comment( page_title=page.page_title, space=page.page_space, confluence=confluence_instance, ) == "")
def test_validate_with_quiet(online, make_one_page_config): config_file, config = make_one_page_config result: Result = run_with_config(config_file=config_file, pre_args=["--quiet"], other_args=["--online"] * online) assert result.exit_code == 0 assert result.stdout == ""
def test_post_force_overwrite_other_author(force_flag, tmp_path, setup_page): """Checks that force flag overwrites page if the author is different""" config_file, (page_id, page_title) = setup_page(1) original_username = Config(config_file).author new_config = replace_new_author(config_file=config_file, tmp_path=tmp_path) new_text = rewrite_page_file(Config(new_config).pages[0].page_file) new_username = Config(new_config).author result = run_with_config( config_file=new_config, pre_args=["--force"] * force_flag, ) assert result.exit_code == 0 if force_flag: assert ( "Updating page" in result.stdout ), "User should be notified an update is happening" assert new_text in get_page_body(page_id), "Page should had been updated" check_body_and_title(page_id, body_text=new_text, title_text=page_title) else: assert "Flag 'force' is not set and last author" in result.stdout, ( "User should be notified why the script " "is not updating anything" ) assert ( original_username in result.stdout ), "The original username should be mentioned in the script output" assert ( new_username in result.stdout ), "The author_to_check username should be mentioned in the script output" assert new_text not in get_page_body( page_id ), "Page should not had been updated"
def test_convert_markdown(make_one_page_config, tmp_path, text_source): config_file, config = make_one_page_config md_text = "# Header\nTest\n\n* One\n* Two" if text_source == "file": md_file = tmp_path / "file.md" md_file.write_text(md_text) _source = md_file _input = "" else: _source = "-" _input = md_text result: Result = run_with_config( config_file=config_file, other_args=[ _source, "--force-create", "convert-markdown", ], input=_input, ) assert result.exit_code == 0 assert (result.stdout == """<h1>Header</h1> <p>Test</p> <ul> <li>One</li> <li>Two</li> </ul> """)
def run_with_comment(comment: str): _result: Result = run_with_config(config_file=config_file, input="Y\n" "N\n" "Y\n", other_args=[comment]) assert _result.exit_code == 0 return _result
def test_all_ok(make_one_page_config): """Validates that the validate --online does not break during execution""" config_file, config = make_one_page_config result: Result = run_with_config(config_file=config_file, other_args=["--online"]) assert "Validating settings" in result.stdout assert "Trying to get" in result.stdout assert "Validation successful" in result.stdout assert "Got space id" in result.stdout
def test_other_commands(make_one_page_config, tmp_path, command): config_file, config = make_one_page_config _, content, page_file = generate_fake_page(tmp_path) result: Result = run_with_config( config_file=config_file, other_args=["-", "--force-create", f"{command}"], input=content, ) assert result.exit_code == 3 assert "not compatible" in result.stderr
def test_force_overwrite_one_page(tmp_path, setup_page): config_file, _ = setup_page(1) new_config = _set_page_to_overwrite(config_file, 1, tmp_path) new_config = replace_new_author(new_config, tmp_path) rewrite_page_file(Config(new_config).pages[0].page_file) result: Result = run_with_config(new_config) assert result.exit_code == 0 assert "Updating page" in result.stdout assert "force overwrite" in result.stdout
def test_could_not_connect(tmp_path): """Checks that validation fails against a non-existent instance of Confluence""" config = mk_local_config( tmp_path, key_to_update="auth.confluence_url", value_to_update="http://localhost:64000", ) result: Result = run_with_config(config_file=config, other_args=["--online"]) assert result.exit_code == 1 assert "Could not connect" in result.stderr
def test_nonexistent_space(tmp_path): """Checks that the API returns the error about nonexistent space""" config = mk_local_config( tmp_path, key_to_update="pages.page1.page_space", value_to_update="nonexistent_space_key", ) result: Result = run_with_config(config_file=config, other_args=["--online"]) assert result.exit_code == 1 assert "API error" in result.stderr
def test_force_flag_single_page(tmp_path, setup_page): """Tests that the --force flag works with force_overwrite flag - page gets updated""" config_file, _ = setup_page(1) new_config = _set_page_to_overwrite(config_file, 1, tmp_path) new_config = replace_new_author(new_config, tmp_path) rewrite_page_file(Config(new_config).pages[0].page_file) result: Result = run_with_config(new_config, pre_args=["--force"]) assert result.exit_code == 0 assert "Updating page" in result.stdout assert "force overwrite" not in result.stdout
def test_post_page_with_real_file(make_one_page_config, tmp_path): config_file, config = make_one_page_config _, content, page_file = generate_fake_page(tmp_path) result: Result = run_with_config( config_file=config_file, other_args=[page_file, "post-page"], input=create_single_page_input, ) assert result.exit_code == 0 assert get_page_body(get_page_id_from_stdout( result.stdout)) == f"<p>{content}</p>"
def test_create_and_overwrite_page(force_flag, setup_page): """Creates a page and tries to overwrite it as the same user. Checks that the force_flag does not matter""" config_file, (page_id, page_title) = setup_page(1) new_text = rewrite_page_file(Config(config_file).pages[0].page_file) overwrite_result = run_with_config( config_file=config_file, pre_args=["--force"] * force_flag, ) assert overwrite_result.exit_code == 0 assert "Updating page" in overwrite_result.stdout check_body_and_title(page_id, body_text=new_text, title_text=page_title)
def test_create_one_page_in_space_root(tmp_path, page_count): config_file, config = generate_local_config(tmp_path, pages=page_count) result: Result = run_with_config(config_file=config_file, input=join_input(user_input=("Y", ) * page_count)) created_pages = get_pages_ids_from_stdout(result.stdout) assert result.exit_code == 0 assert (result.stderr is "" ) # if parent is not found - get_parent_content_id logs to stderr assert len(created_pages) == page_count for page_id in created_pages: parent = confluence_instance.get_parent_content_id(page_id) assert parent is None, "Page should had been created in space root"
def test_not_create_if_refused(make_one_page_config): config_file, config = make_one_page_config result = run_with_config( input=join_input("N"), config_file=config_file, ) assert result.exit_code == 0 assert ("Not creating page" in result.stdout), "Script did not report that page is not created" assert not page_created(page_title=config.pages[0].page_title ), "Page was not supposed to be created" assert (len(get_pages_ids_from_stdout( result.stdout)) == 0), "Detected a page that was created!"
def test_force_create_pages(tmp_path, page_count): """Runs confluence_poster post-page --force-create""" config_file, config = generate_local_config(tmp_path, pages=page_count) result = run_with_config( config_file=config_file, pre_args=["--force-create"], input=join_input(user_input=("N", "Y") * page_count), ) assert result.exit_code == 0 assert "Should it be created?" not in result.stdout # flag overwrites the prompt for page in config.pages: assert page_created(page.page_title, page.page_space), "Page was supposed to be created"
def test_post_single_page_with_parent(setup_page, parent_page_title_source, tmp_path): """Tests that the parent_page_title is applied to create the page in the proper place. Tests scenarios of providing the parent title in dialog (through user input), as --parent-page-title argument, or in config""" # Create the first page, it will be the parent config, (parent_id, parent_page_title) = setup_page(1) page_title = next(fake_title_generator) if parent_page_title_source == "dialog": result, _ = run_with_title( input=join_input("Y", "Y", parent_page_title, "Y"), config_file=real_confluence_config, ) assert "Which page should the script look for?" in result.stdout assert "URL is:" in result.stdout assert "Proceed to create the page" in result.stdout else: if parent_page_title_source == "cmdline": result = run_with_config( input=f"Y\n", # create page pre_args=[ "--parent-page-title", parent_page_title, "--page-title", page_title, ], config_file=real_confluence_config, ) else: config_file = mk_tmp_file( tmp_path=tmp_path, key_to_update="pages.page1.page_parent_title", value_to_update=parent_page_title, ) result, _ = run_with_title( input=f"Y\n", config_file=config_file # create page ) assert ( "Which page should the script look for?" not in result.stdout ), "If the parent page title is explicitly supplied, script should not look for parent" assert "Found page #" in result.stdout assert result.exit_code == 0 assert get_page_id_from_stdout( result.stdout) in confluence_instance.get_child_id_list(parent_id)
def test_search_for_parent_multiple_times(make_one_page_config): """Checks that the user can retry searching for a parent if it is not found""" config_file, config = make_one_page_config attempts = 3 # how many times to try to look for parent nl = "\n" # to work around f-string '\' limitation result = run_with_config( input="Y\n" # create page f"{attempts * ('Y' + nl + next(fake_title_generator) + nl)}" # try to look "N\n" # finally, refuse to look for parent "Y\n", # create in root config_file=config_file, ) assert result.exit_code == 0 assert (result.stdout.count("Should the script look for a parent in space") == attempts + 1) # +1 because refusal
def test_create_page_under_nonexistent_parent(tmp_path, make_one_page_config): """Tries to create a page under a non-existent parent, ensures that it fails and reports""" config_file, config = make_one_page_config parent_page_title = next(fake_title_generator) config_file = mk_tmp_file( tmp_path=tmp_path, config_to_clone=config_file, key_to_update="pages.page1.page_parent_title", value_to_update=parent_page_title, ) result = run_with_config(input=f"Y\n", config_file=config_file) # create page assert result.exit_code == 0 assert f"page '{parent_page_title}' not found" in result.stdout assert "Skipping page" in result.stdout
def test_convert_online(make_one_page_config): config_file, config = make_one_page_config Path(config.pages[0].page_file).write_text("# Title\n* one\n* two") result = run_with_config( config_file=config_file, other_args=["--use-confluence-converter"] ) assert result.stdout == """<h1>Title</h1> <ul> <li>one <li>two </ul> \n""" assert ( "Using the converter built into Confluence which is labeled as private API." in result.stderr ), "This command uses Confluence private API, user should be warned" assert ( "file-format html" in result.stderr ), "Recommendation about file format should be given"
def test_warn_user_could_not_guess_file(tmp_path, make_one_page_config): config_file, config = make_one_page_config config_file = mk_tmp_file( tmp_path=tmp_path, config_to_clone=config_file, key_to_update="pages.page1.page_file", value_to_update="filename_no_extension", ) result: Result = run_with_config( config_file=config_file, input=create_single_page_input, ) assert "--help" in result.stdout assert result.exit_code == 1
def run_with_title( page_title: str = None, fake_title=True, *args, **kwargs, ): """Helper function to create pages with specific title. Generates fake title by default""" if page_title is None and fake_title: page_title = next(fake_title_generator) elif fake_title is False and page_title is None: raise ValueError("Fake title is False and no real title was provided") return ( run_with_config(pre_args=["--page-title", page_title], *args, **kwargs), page_title, )
def _create_pages(page_count: int = 1) -> Tuple[str, List[Tuple[int, str]]]: page_list = [] config_file, config = generate_local_config(tmp_path, pages=page_count) runner = CliRunner() run_cmd = generate_run_cmd(runner=runner, app=app, default_args=["post-page"]) result = run_with_config( input=join_input(user_input=("Y", "N", "Y") * page_count), config_file=config_file, record_pages=record_pages, default_run_cmd=run_cmd, ) assert result.exit_code == 0 created_page_ids = get_pages_ids_from_stdout(result.stdout) for number, page in enumerate(config.pages): page_list += (created_page_ids[number], page.page_title) return config_file, page_list
def test_convert_command_default_behavior(make_one_page_config): """Makes sure that there is no extra output in stdout when running the tool""" config_file, config = make_one_page_config Path(config.pages[0].page_file).write_text("# Title\n* one\n* two") result = run_with_config(config_file=config_file, other_args=[]) assert result.exit_code == 0 assert ( result.stdout == """<h1>Title</h1> <ul> <li>one</li> <li>two</li> </ul> """ )
def test_post_page_report(make_one_page_config): config_file, config = make_one_page_config result = run_with_config(input=join_input("N"), config_file=config_file) assert result.exit_code == 0 assert ("Not creating page" in result.stdout), "Script did not report that page is not created" assert not page_created(page_title=config.pages[0].page_title ), "Page was not supposed to be created" assert (len(get_pages_ids_from_stdout( result.stdout)) == 0), "Detected a page that was created!" page = config.pages[0] assert get_page_url(page.page_title, page.page_space, confluence_instance) is None assert ("Created pages:\nNone\nUpdated pages:\nNone\nUnprocessed pages:" in result.stdout) assert ( f"{page.page_space}::{page.page_title} Reason: User cancelled creation when prompted" in result.stdout)
def test_post_single_page_no_parent(make_one_page_config): """Test with good default config, to check that everything is OK. Creates a sample page in the root of the space Author's note: mirrors setup_page fixture, but kept separately to make failures clearer""" config_file, config = make_one_page_config result = run_with_config( config_file=config_file, input=create_single_page_input, ) assert result.exit_code == 0 assert "Looking for page" in result.stdout assert "Should the page be created?" in result.stdout # checking the prompt assert ("Should the script look for a parent in space" in result.stdout) # checking the prompt assert "Create the page in the root" in result.stdout # checking the prompt assert f"Could not find page '{config.pages[0].page_title}'" in result.stdout assert "Creating page" in result.stdout assert "Created page" in result.stdout assert "Finished processing pages" in result.stdout
def test_upload_files_single_page_title_supplied(setup_page, gen_attachments): """Runs confluence_poster --config <config> --page-title <some page name> post-page --upload-files file1 file2... And makes sure the files were attached to the proper page """ page_id, config_file = setup_page file_to_upload, filename = gen_attachments[0] new_title = next(fake_title_generator) # Create the page first create_page = run_with_config( config_file=config_file, pre_args=["--page-title", new_title], default_run_cmd=generate_run_cmd(runner, app, default_args=["post-page"]), input="Y\nN\nY\n", ) created_page_id = get_page_id_from_stdout(create_page.stdout) result: Result = upload_files( config_file=config_file, other_args=[file_to_upload], pre_args=["--page-title", new_title], ) assert result.exit_code == 0 assert ( len( confluence_instance.get_attachments_from_content(created_page_id)["results"] ) == 1 ) assert ( confluence_instance.get_attachments_from_content(created_page_id)["results"][0][ "title" ] == filename ) assert ( len(confluence_instance.get_attachments_from_content(page_id)["results"]) == 0 ), "The original page should not have any attachments"
def test_post_new_page_stdin(make_one_page_config, tmp_path, file_format): """Tests posting three sources with the effectively same text""" config_file, config = make_one_page_config content = { "html": """<h1>Title</h1> <ul> <li>one</li> <li>two</li> </ul>""", "confluencewiki": """h1. Title * one * two""", "markdown": """# Title * one * two""", } result: Result = run_with_config( config_file=config_file, other_args=[ "-", "--force-create", "post-page", "--create-in-space-root", "--file-format", file_format, ], input=content[file_format], ) assert result.exit_code == 0 assert BeautifulSoup( get_page_body(get_page_id_from_stdout(result.stdout)), features="lxml", ) == BeautifulSoup( content["html"], features="lxml", )
def test_force_overwrite_two_pages(overwrite_pages, tmp_path, setup_page): """Checks for multiple pages force overwrite flag is set <=> page is updated if author is changed""" pages_obj = {1: {}, 2: {}} config_file, ( pages_obj[1]["page_id"], pages_obj[1]["page_title"], pages_obj[2]["page_id"], pages_obj[2]["page_title"], ) = setup_page(2) new_config = replace_new_author(config_file, tmp_path) for page_no in range(2): if overwrite_pages[page_no]: new_config = _set_page_to_overwrite( config_file=new_config, page_no=page_no + 1, tmp_path=tmp_path ) rewrite_page_file(Config(new_config).pages[page_no].page_file) result: Result = run_with_config(new_config) assert result.exit_code == 0 for page_no in range(2): assert ( f"Updating page #{pages_obj[page_no+1]['page_id']}" in result.stdout ) == overwrite_pages[page_no]