Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
252 changes: 0 additions & 252 deletions kitsune/customercare/__init__.py
Original file line number Diff line number Diff line change
@@ -1,252 +0,0 @@
from typing import TypedDict


class TagsDict(TypedDict):
legacy: str
tiers: list[str]
automation: str | None
segmentation: str | None


class CategoryDict(TypedDict):
slug: str
topic: str
tags: TagsDict


BASE_CATEGORIES: dict[str, CategoryDict] = {
"payments": {
"slug": "payments",
"topic": "I need help with a billing or subscription question",
"tags": {
"legacy": "payments",
"tiers": ["t1-billing-and-subscriptions"],
"automation": None,
"segmentation": None,
},
},
"accounts_signin": {
"slug": "account-signin",
"topic": "I can't sign in to my Mozilla account or subscription",
"tags": {
"legacy": "accounts",
"tiers": ["t1-passwords-and-sign-in", "t2-sign-in", "t3-sign-in-failure"],
"automation": "ssa-sign-in-failure-automation",
"segmentation": None,
},
},
"general": {
"slug": "general",
"topic": "I want to share feedback or suggest a feature",
"tags": {
"legacy": "general",
"tiers": ["general"],
"automation": None,
"segmentation": None,
},
},
"not_listed": {
"slug": "not-listed",
"topic": "My issue isn't listed here",
"tags": {
"legacy": "not_listed",
"tiers": ["not_listed"],
"automation": None,
"segmentation": None,
},
},
}

ZENDESK_CATEGORIES = {
"mozilla-vpn": [
{
"slug": "vpn-connection-issues",
"topic": "I can't connect to Mozilla VPN",
"tags": {
"legacy": "technical",
"tiers": [
"t1-performance-and-connectivity",
"t2-connectivity",
"t3-connection-failure",
],
"automation": "ssa-connection-issues-automation",
"segmentation": None,
},
},
{
"slug": "vpn-installation-updates",
"topic": "I need help installing or updating Mozilla VPN",
"tags": {
"legacy": "technical",
"tiers": ["t1-installation-and-updates"],
"automation": None,
"segmentation": None,
},
},
{
"slug": "vpn-server-selection",
"topic": "I can't choose a VPN location",
"tags": {
"legacy": "technical",
"tiers": [
"t1-performance-and-connectivity",
"t2-connectivity",
"t3-cant-select-server",
],
"automation": None,
"segmentation": None,
},
},
*BASE_CATEGORIES.values(),
],
"relay": [
{
"slug": "relay-email-forwarding",
"topic": "I'm not receiving emails to my Relay mask",
"tags": {
"legacy": "technical",
"tiers": ["t1-privacy-and-security", "t2-masking", "t3-email-masking"],
"automation": None,
"segmentation": "seg-relay-no-fwd-deliver",
},
},
{
"slug": "relay-domain-change",
"topic": "I want to change my Relay email domain",
"tags": {
"legacy": "technical",
"tiers": ["t1-privacy-and-security", "t2-masking", "t3-email-masking"],
"automation": None,
"segmentation": "seg-relay-chg-domain",
},
},
*BASE_CATEGORIES.values(),
],
"pocket": [
BASE_CATEGORIES["not_listed"],
BASE_CATEGORIES["accounts_signin"],
],
"mozilla-account": [
{
"slug": "mozilla-account-sync",
"topic": "I need help with Firefox Sync",
"tags": {
"legacy": "accounts",
"tiers": ["t1-backup-recovery-and-sync"],
"automation": "ssa-sync-data-automation",
"segmentation": None,
},
},
{
"slug": "mozilla-account-delete",
"topic": "I want to delete my Mozilla account",
"tags": {
"legacy": "accounts",
"tiers": ["t1-accounts", "t2-account-management"],
"automation": None,
"segmentation": "seg-acct-delete",
},
},
*BASE_CATEGORIES.values(),
],
"monitor": [
{
"slug": "monitor-data-removal",
"topic": "My data removal is taking too long",
"tags": {
"legacy": "technical",
"tiers": ["t1-privacy-and-security", "t2-data-removal", "t3-data-brokers"],
"automation": None,
"segmentation": "seg-mntor-slow-remove",
},
},
{
"slug": "monitor-wrong-results",
"topic": "I'm seeing results that don't belong to me",
"tags": {
"legacy": "technical",
"tiers": [
"t1-privacy-and-security",
"t2-data-removal",
"t3-privacy-protection-scan",
],
"automation": None,
"segmentation": "seg-mntor-wrong-scan-result",
},
},
*BASE_CATEGORIES.values(),
],
"mdn-plus": [
*BASE_CATEGORIES.values(),
],
}

ZENDESK_CATEGORIES_LOGINLESS = {
"mozilla-account": [
{
"slug": "fxa-2fa-lockout",
"topic": "My security code isn't working or is lost",
"tags": {
"legacy": "accounts",
"tiers": [
"t1-passwords-and-sign-in",
"t2-two-factor-authentication",
"t3-two-factor-lockout",
],
"automation": "ssa-2fa-automation",
"segmentation": None,
},
},
{
"slug": "fxa-emailverify-lockout",
"topic": "I can't recover my account using email",
"tags": {
"legacy": "accounts",
"tiers": ["t1-passwords-and-sign-in", "t2-sign-in", "t3-email-verify-lockout"],
"automation": "ssa-pwrdreset-automation",
"segmentation": None,
},
},
{
"slug": "fxa-reset-password",
"topic": "I forgot my password",
"tags": {
"legacy": "accounts",
"tiers": ["t1-passwords-and-sign-in", "t2-reset-passwords"],
"automation": "ssa-emailverify-automation",
"segmentation": None,
},
},
{
"slug": "fxa-remove3rdprtylogin",
"topic": "I'm having issues signing in with my Google or Apple ID",
"tags": {
"legacy": "accounts",
"tiers": ["t1-passwords-and-sign-in", "t2-sign-in", "t3-3rd-party-sign-in"],
"automation": None,
"segmentation": None,
},
},
]
}


ZENDESK_LEGACY_MAPPING: dict[str, set] = {
"accounts": {
"t1-accounts",
"t1-passwords-and-sign-in",
},
"technical": {
"t1-accessibility",
"t1-backup-recovery-and-sync",
"t1-browse",
"t1-download-and-save",
"t1-email-and-messaging",
"t1-installation-and-updates",
"t1-performance-and-connectivity",
"t1-privacy-and-security",
"t1-search-tag-and-share",
"t1-settings",
},
"payment": {"t1-billing-and-subscriptions"},
}
77 changes: 47 additions & 30 deletions kitsune/customercare/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@
generate_classification_tags,
send_support_ticket_to_zendesk,
)
from kitsune.products.tests import ProductFactory, TopicFactory
from kitsune.products.tests import (
ProductFactory,
ProductSupportConfigFactory,
TopicFactory,
ZendeskConfigFactory,
ZendeskTopicConfigurationFactory,
ZendeskTopicFactory,
)
from kitsune.sumo.tests import TestCase


Expand Down Expand Up @@ -86,7 +93,7 @@ def test_single_tier_topic(self):

tags = generate_classification_tags(submission, result)

self.assertEqual(tags, ["t1-settings", "technical"])
self.assertEqual(tags, ["t1-settings", "general"])

def test_two_tier_topic(self):
"""Test generating tags for a tier 2 topic."""
Expand All @@ -100,7 +107,7 @@ def test_two_tier_topic(self):

tags = generate_classification_tags(submission, result)

self.assertEqual(tags, ["t1-settings", "t2-notifications", "technical"])
self.assertEqual(tags, ["t1-settings", "t2-notifications", "general"])

def test_three_tier_topic(self):
"""Test generating tags for a tier 3 topic."""
Expand All @@ -119,27 +126,32 @@ def test_three_tier_topic(self):
tags = generate_classification_tags(submission, result)

self.assertEqual(
tags, ["t1-settings", "t2-addons-extensions-and-themes", "t3-extensions", "technical"]
tags, ["t1-settings", "t2-addons-extensions-and-themes", "t3-extensions", "general"]
)

@patch("kitsune.customercare.utils.ZENDESK_CATEGORIES")
def test_automation_tag_included_when_matched(self, mock_categories):
def test_automation_tag_included_when_matched(self):
"""Test that automation tag is included when tier tags match a category."""
mock_categories.get.return_value = [
{
"slug": "accounts-signin",
"tags": {
"tiers": ["t1-passwords-and-sign-in", "t2-sign-in"],
"automation": "ssa-sign-in-failure-automation",
},
}
]

tier1 = TopicFactory(title="Passwords and sign in", parent=None, is_archived=False)
tier1.products.add(self.product)
tier2 = TopicFactory(title="Sign in", parent=tier1, is_archived=False)
tier2.products.add(self.product)

# Create ZendeskConfig and ZendeskTopic with matching tier tags
zendesk_config = ZendeskConfigFactory(name="Test Config")
zendesk_topic = ZendeskTopicFactory(
slug="accounts-signin",
topic="I can't sign in",
tier_tags=["t1-passwords-and-sign-in", "t2-sign-in"],
automation_tag="ssa-sign-in-failure-automation",
legacy_tag="accounts",
)
ZendeskTopicConfigurationFactory(
zendesk_config=zendesk_config, zendesk_topic=zendesk_topic
)
ProductSupportConfigFactory(
product=self.product, zendesk_config=zendesk_config, is_active=True
)

submission = Mock(product=self.product)
result = {"topic_result": {"topic": "Sign in"}}

Expand All @@ -150,28 +162,33 @@ def test_automation_tag_included_when_matched(self, mock_categories):
self.assertIn("t2-sign-in", tags)
self.assertIn("accounts", tags)

@patch("kitsune.customercare.utils.ZENDESK_CATEGORIES")
def test_no_automation_tag_when_not_matched(self, mock_categories):
def test_no_automation_tag_when_not_matched(self):
"""Test that no automation tag is included when tier tags don't match."""
mock_categories.get.return_value = [
{
"slug": "different-category",
"tags": {
"tiers": ["t1-different"],
"automation": "some-automation",
},
}
]

tier1 = TopicFactory(title="Billing and subscriptions", parent=None, is_archived=False)
tier1.products.add(self.product)

# Create ZendeskConfig with a ZendeskTopic that has different tier tags
zendesk_config = ZendeskConfigFactory(name="Test Config")
zendesk_topic = ZendeskTopicFactory(
slug="different-category",
topic="Different topic",
tier_tags=["t1-different"],
automation_tag="some-automation",
legacy_tag="",
)
ZendeskTopicConfigurationFactory(
zendesk_config=zendesk_config, zendesk_topic=zendesk_topic
)
ProductSupportConfigFactory(
product=self.product, zendesk_config=zendesk_config, is_active=True
)

submission = Mock(product=self.product)
result = {"topic_result": {"topic": "Billing and subscriptions"}}

tags = generate_classification_tags(submission, result)

self.assertEqual(tags, ["t1-billing-and-subscriptions", "payment"])
self.assertEqual(tags, ["t1-billing-and-subscriptions", "general"])
self.assertNotIn("some-automation", tags)

def test_product_reassignment_includes_other_tag(self):
Expand All @@ -189,7 +206,7 @@ def test_product_reassignment_includes_other_tag(self):

self.assertIn("other", tags)
self.assertIn("t1-settings", tags)
self.assertIn("technical", tags)
self.assertIn("general", tags)

def test_archived_topic_returns_undefined(self):
"""Test that archived topics are not found and return ['undefined', 'general']."""
Expand Down
Loading