mirror of
https://github.com/zulip/zulip.git
synced 2025-10-22 20:42:14 +00:00
Compare commits
11 Commits
d1cedb7f1d
...
6b6a02f932
Author | SHA1 | Date | |
---|---|---|---|
|
6b6a02f932 | ||
|
f317af2e1d | ||
|
f6e847d026 | ||
|
883c27e991 | ||
|
be5189774b | ||
|
b1376a8cac | ||
|
0048902853 | ||
|
7b5e4db7ee | ||
|
e7922e2472 | ||
|
326c7d6383 | ||
|
24437963e2 |
BIN
static/images/integrations/git/001.png
Normal file
BIN
static/images/integrations/git/001.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 61 KiB |
BIN
static/images/integrations/jira-plugin/001.png
Normal file
BIN
static/images/integrations/jira-plugin/001.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
@@ -540,13 +540,6 @@ input.settings_text_input {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#convert-demo-organization-form,
|
||||
#invite-user-form {
|
||||
.banner-action-buttons {
|
||||
padding: 0.085em 0;
|
||||
}
|
||||
}
|
||||
|
||||
.create-group-button-container {
|
||||
.upgrade-organization-banner-container {
|
||||
display: flex;
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<div class="alert" id="dev_env_msg"></div>
|
||||
{{/if}}
|
||||
{{#if (not user_has_email_set) }}
|
||||
<div class="demo-organization-add-email-banner"></div>
|
||||
<div class="demo-organization-add-email-banner banner-wrapper"></div>
|
||||
{{/if}}
|
||||
<div class="input-group">
|
||||
<div id="invite_users_option_tabs_container"></div>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<div id="convert-demo-organization-form">
|
||||
{{#unless user_has_email_set}}
|
||||
<div class="demo-organization-add-email-banner"></div>
|
||||
<div class="demo-organization-add-email-banner banner-wrapper"></div>
|
||||
{{/unless}}
|
||||
<p>{{t "Everyone will need to log in again at the new URL for your organization." }}</p>
|
||||
<form class="subdomain-setting">
|
||||
|
@@ -46,6 +46,7 @@ META_CATEGORY: dict[str, StrPromise] = {
|
||||
|
||||
CATEGORIES: dict[str, StrPromise] = {
|
||||
**META_CATEGORY,
|
||||
"video-calling": gettext_lazy("Video calling"),
|
||||
"continuous-integration": gettext_lazy("Continuous integration"),
|
||||
"customer-support": gettext_lazy("Customer support"),
|
||||
"deployment": gettext_lazy("Deployment"),
|
||||
@@ -69,9 +70,11 @@ FIXTURELESS_INTEGRATIONS_WITH_SCREENSHOTS: list[str] = [
|
||||
"capistrano",
|
||||
"codebase",
|
||||
"discourse",
|
||||
"git",
|
||||
"github-actions",
|
||||
"google-calendar",
|
||||
"jenkins",
|
||||
"jira-plugin",
|
||||
"mastodon",
|
||||
"mercurial",
|
||||
"nagios",
|
||||
@@ -607,7 +610,7 @@ WEBHOOK_INTEGRATIONS: list[WebhookIntegration] = [
|
||||
INTEGRATIONS: dict[str, Integration] = {
|
||||
"asana": Integration("asana", ["project-management"]),
|
||||
"big-blue-button": Integration(
|
||||
"big-blue-button", ["communication"], display_name="BigBlueButton"
|
||||
"big-blue-button", ["video-calling", "communication"], display_name="BigBlueButton"
|
||||
),
|
||||
"capistrano": Integration("capistrano", ["deployment"], display_name="Capistrano"),
|
||||
"discourse": Integration("discourse", ["communication"]),
|
||||
@@ -622,13 +625,13 @@ INTEGRATIONS: dict[str, Integration] = {
|
||||
),
|
||||
"hubot": Integration("hubot", ["meta-integration", "bots"]),
|
||||
"jenkins": Integration("jenkins", ["continuous-integration"]),
|
||||
"jitsi": Integration("jitsi", ["communication"], display_name="Jitsi Meet"),
|
||||
"jitsi": Integration("jitsi", ["video-calling", "communication"], display_name="Jitsi Meet"),
|
||||
"mastodon": Integration("mastodon", ["communication"]),
|
||||
"notion": Integration("notion", ["productivity"]),
|
||||
"onyx": Integration("onyx", ["productivity"], logo="images/integrations/logos/onyx.png"),
|
||||
"puppet": Integration("puppet", ["deployment"]),
|
||||
"redmine": Integration("redmine", ["project-management"]),
|
||||
"zoom": Integration("zoom", ["communication"]),
|
||||
"zoom": Integration("zoom", ["video-calling", "communication"]),
|
||||
}
|
||||
|
||||
PYTHON_API_INTEGRATIONS: list[PythonAPIIntegration] = [
|
||||
@@ -715,13 +718,41 @@ for webhook_integration in WEBHOOK_INTEGRATIONS:
|
||||
for bot_integration in BOT_INTEGRATIONS:
|
||||
INTEGRATIONS[bot_integration.name] = bot_integration
|
||||
|
||||
# Add integrations that don't have automated screenshots here
|
||||
NO_SCREENSHOT_WEBHOOKS = {
|
||||
"beeminder", # FIXME: fixture's goal.losedate needs to be modified dynamically
|
||||
"ifttt", # Docs don't have a screenshot
|
||||
"slack_incoming", # Docs don't have a screenshot
|
||||
"zapier", # Docs don't have a screenshot
|
||||
}
|
||||
# Add webhook integrations that don't have automated screenshots here
|
||||
NO_SCREENSHOT_WEBHOOKS = (
|
||||
# FIXME: fixture's goal.losedate needs to be modified dynamically
|
||||
{"beeminder"}
|
||||
# Meta integrations - Docs won't have a screenshot
|
||||
| {"ifttt", "slack_incoming", "zapier"}
|
||||
)
|
||||
|
||||
hubot_integration_names = {integration.name for integration in HUBOT_INTEGRATIONS}
|
||||
|
||||
# Add fixtureless integrations that don't have automated screenshots here
|
||||
NO_SCREENSHOT_CONFIG = (
|
||||
# Outgoing integrations - Docs won't have a screenshot
|
||||
{"email", "onyx"}
|
||||
# Video call integrations - Docs won't have a screenshot
|
||||
| {"big-blue-button", "jitsi", "zoom"}
|
||||
# Integrations that require screenshots of message threads - support is yet to be added
|
||||
| {
|
||||
"errbot",
|
||||
"github_detail",
|
||||
"hubot",
|
||||
"irc",
|
||||
# Also requires a screenshot on the Matrix side of the bridge
|
||||
"matrix",
|
||||
"xkcd",
|
||||
}
|
||||
| {
|
||||
# Doc doesn't have a screenshot
|
||||
"giphy",
|
||||
# the integration is planned to be removed
|
||||
"twitter",
|
||||
}
|
||||
| NO_SCREENSHOT_WEBHOOKS
|
||||
| hubot_integration_names
|
||||
)
|
||||
|
||||
|
||||
WEBHOOK_SCREENSHOT_CONFIG: dict[str, list[WebhookScreenshotConfig]] = {
|
||||
|
@@ -20306,6 +20306,10 @@ paths:
|
||||
names contained in this list, to obtain the desired
|
||||
thumbnail size.
|
||||
|
||||
See [Images in Markdown messages](/api/message-formatting#images)
|
||||
for details of how Zulip renders images, and how
|
||||
clients should handle them.
|
||||
|
||||
**Changes**: New in Zulip 9.0 (feature level 273).
|
||||
type: array
|
||||
items:
|
||||
@@ -20332,7 +20336,7 @@ paths:
|
||||
type: boolean
|
||||
description: |
|
||||
If this file format is animated. These formats
|
||||
are only generated for uploaded imates which
|
||||
are only generated for uploaded images which
|
||||
themselves are animated.
|
||||
server_avatar_changes_disabled:
|
||||
type: boolean
|
||||
|
@@ -413,6 +413,14 @@ class DocPageTest(ZulipTestCase):
|
||||
not in (image_path := os.path.relpath(os.path.join(root, file), directory))
|
||||
}
|
||||
|
||||
# The integration docs and the screenshot images are in different repos
|
||||
# for the PythonAPIIntegrations, so we cannot avoid going out of sync
|
||||
# when adding/deleting screenshots.
|
||||
# Use this set to temporarily add exclusions to this test.
|
||||
exception_images: set[str] = {"jira-plugin/001.png", "git/001.png"}
|
||||
images_in_dir.update(exception_images)
|
||||
images_in_docs.update(exception_images)
|
||||
|
||||
self.assertEqual(
|
||||
images_in_dir,
|
||||
images_in_docs,
|
||||
|
@@ -1,10 +1,9 @@
|
||||
import os
|
||||
|
||||
from zerver.lib.integrations import (
|
||||
DOC_SCREENSHOT_CONFIG,
|
||||
INTEGRATIONS,
|
||||
NO_SCREENSHOT_WEBHOOKS,
|
||||
WEBHOOK_INTEGRATIONS,
|
||||
WEBHOOK_SCREENSHOT_CONFIG,
|
||||
NO_SCREENSHOT_CONFIG,
|
||||
WebhookIntegration,
|
||||
WebhookScreenshotConfig,
|
||||
get_fixture_path,
|
||||
@@ -41,37 +40,65 @@ class IntegrationsTestCase(ZulipTestCase):
|
||||
self.assertIsNone(integration.get_bot_avatar_path())
|
||||
|
||||
def test_no_missing_doc_screenshot_config(self) -> None:
|
||||
webhook_names = {webhook.name for webhook in WEBHOOK_INTEGRATIONS}
|
||||
webhooks_with_screenshot_config = set(WEBHOOK_SCREENSHOT_CONFIG.keys())
|
||||
missing_webhooks = webhook_names - webhooks_with_screenshot_config - NO_SCREENSHOT_WEBHOOKS
|
||||
message = (
|
||||
f"These webhooks are missing screenshot config: {missing_webhooks}.\n"
|
||||
"Add them to zerver.lib.integrations.DOC_SCREENSHOT_CONFIG"
|
||||
integration_names = {integration.name for integration in INTEGRATIONS.values()}
|
||||
integrations_with_screenshot_configs = set(DOC_SCREENSHOT_CONFIG.keys())
|
||||
|
||||
missing_integration_screenshots = (
|
||||
integration_names - integrations_with_screenshot_configs - NO_SCREENSHOT_CONFIG
|
||||
)
|
||||
extra_integration_configs = integrations_with_screenshot_configs - integration_names
|
||||
extra_integration_no_configs = NO_SCREENSHOT_CONFIG - integration_names
|
||||
|
||||
def construct_message(title: str, integrations: set[str], action: str) -> str:
|
||||
return (
|
||||
f"\n\n{title}\n" + "\n".join(integrations) + f"\n{action}" if integrations else ""
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
integrations_with_screenshot_configs,
|
||||
integration_names - NO_SCREENSHOT_CONFIG,
|
||||
construct_message(
|
||||
"The following integrations are missing their example screenshot configuration:",
|
||||
missing_integration_screenshots,
|
||||
"Add them to zerver.lib.integrations.DOC_SCREENSHOT_CONFIG",
|
||||
)
|
||||
+ construct_message(
|
||||
"The following integrations have a screenshot configuration but no longer exist:",
|
||||
extra_integration_configs,
|
||||
"Remove them from zerver.lib.integrations.DOC_SCREENSHOT_CONFIG",
|
||||
)
|
||||
+ construct_message(
|
||||
"The following integrations are listed in NO_SCREENSHOT_CONFIG but no longer exist:",
|
||||
extra_integration_no_configs,
|
||||
"Remove them from zerver.lib.integrations.NO_SCREENSHOT_CONFIG",
|
||||
),
|
||||
)
|
||||
self.assertFalse(missing_webhooks, message)
|
||||
|
||||
def test_no_missing_screenshot_path(self) -> None:
|
||||
message = (
|
||||
'"{path}" does not exist for webhook {webhook_name}.\n'
|
||||
"Consider updating zerver.lib.integrations.DOC_SCREENSHOT_CONFIG\n"
|
||||
'and running "tools/screenshots/generate-integration-docs-screenshot" to keep the screenshots up-to-date.'
|
||||
)
|
||||
for integration_name in WEBHOOK_SCREENSHOT_CONFIG:
|
||||
configs = WEBHOOK_SCREENSHOT_CONFIG[integration_name]
|
||||
for screenshot_config in configs:
|
||||
message = '"{path}" does not exist for integration {integration_name}.\n'
|
||||
tip = '\nConsider updating zerver.lib.integrations.DOC_SCREENSHOT_CONFIG\n and running "tools/screenshots/generate-integration-docs-screenshot" to keep the screenshots up-to-date.'
|
||||
error_message = ""
|
||||
|
||||
for integration_name, screenshot_configs in DOC_SCREENSHOT_CONFIG.items():
|
||||
for screenshot_config in screenshot_configs:
|
||||
integration = INTEGRATIONS[integration_name]
|
||||
assert isinstance(integration, WebhookIntegration)
|
||||
if screenshot_config.fixture_name == "":
|
||||
# Such screenshot configs only use a placeholder
|
||||
# fixture_name.
|
||||
continue
|
||||
fixture_path = get_fixture_path(integration, screenshot_config)
|
||||
self.assertTrue(
|
||||
os.path.isfile(fixture_path),
|
||||
message.format(path=fixture_path, webhook_name=integration_name),
|
||||
)
|
||||
if isinstance(integration, WebhookIntegration):
|
||||
assert isinstance(screenshot_config, WebhookScreenshotConfig)
|
||||
if screenshot_config.fixture_name == "":
|
||||
# Skip screenshot configs of webhooks with a placeholder fixture_name
|
||||
continue
|
||||
fixture_path = get_fixture_path(integration, screenshot_config)
|
||||
error_message = (
|
||||
error_message
|
||||
+ message.format(path=fixture_path, integration_name=integration_name)
|
||||
if not os.path.isfile(fixture_path)
|
||||
else error_message
|
||||
)
|
||||
image_path = get_image_path(integration, screenshot_config)
|
||||
self.assertTrue(
|
||||
os.path.isfile(image_path),
|
||||
message.format(path=image_path, webhook_name=integration_name),
|
||||
error_message = (
|
||||
error_message
|
||||
+ message.format(path=image_path, integration_name=integration_name)
|
||||
if not os.path.isfile(image_path)
|
||||
else error_message
|
||||
)
|
||||
self.assertEqual(error_message, "", tip)
|
||||
|
@@ -14,9 +14,11 @@ THREE_DIGIT_NUMBER = "492"
|
||||
|
||||
# Example user content
|
||||
BO_NAME = "Bo Williams"
|
||||
BO_EMAIL = "bwilliams@example.com"
|
||||
BO_GIT_NAME = "bo-williams"
|
||||
|
||||
KEVIN_NAME = "Kevin Lin"
|
||||
KEVIN_EMAIL = "klin@example.com"
|
||||
|
||||
# Example project content
|
||||
PROJECT_NAME = "Example Project"
|
||||
@@ -85,6 +87,14 @@ DISCOURSE = ScreenshotContent(
|
||||
> {COMMIT_BODY_A}""",
|
||||
)
|
||||
|
||||
GIT = ScreenshotContent(
|
||||
topic=BRANCH_GIT,
|
||||
content=f"""`{DEPLOYMENT_HASH[:12]}` was deployed to `{BRANCH_GIT}` with:
|
||||
* {KEVIN_EMAIL} - {COMMIT_HASH_A[:7]}: {COMMIT_MESSAGE_A}
|
||||
* {BO_EMAIL} - {COMMIT_HASH_B[:7]}: {COMMIT_MESSAGE_B}
|
||||
""",
|
||||
)
|
||||
|
||||
GITHUB_ACTIONS = ScreenshotContent(
|
||||
topic="scheduled backups",
|
||||
content=f"""Backup [failed]() at {DATETIME_STAMP}.
|
||||
@@ -104,6 +114,13 @@ JENKINS = ScreenshotContent(
|
||||
content=f"**Build:** [#{REVISION_NUMBER}](): FAILURE :cross_mark:",
|
||||
)
|
||||
|
||||
JIRA_PLUGIN = ScreenshotContent(
|
||||
topic=f"{TICKET_NUMBER}: {TASK_TITLE}",
|
||||
content=f"""{BO_NAME} **created** [{TICKET_NUMBER}]() - priority Medium, assigned to @**{KEVIN_NAME}**:
|
||||
|
||||
> {TASK_DESCRIPTION}""",
|
||||
)
|
||||
|
||||
MASTODON = ScreenshotContent(
|
||||
topic="MIT Technology Review",
|
||||
content=f"""**[Don’t let hype about AI agents get ahead of reality](https://www.technologyreview.com/2025/07/03/1119545/dont-let-hype-about-ai-agents-get-ahead-of-reality/)**
|
||||
|
Reference in New Issue
Block a user