Repository: praw-dev/praw (python)

Issue:
Support for new reddit share link
### Describe the solution you'd like

Within the past couple of weeks, reddit seems to have made a new format for their share links.

Normally, when you click share -> copy link, you would get a link like the following:
https://www.reddit.com/r/space/comments/15llt1x/two_consecutive_solar_flares_send_potential/?ref=share&ref_source=link

However, on mobile, you now get links like the following:
https://reddit.com/r/space/s/skZgKbbMDq
The string after s/ changes every time you share the link, even if it is the same account on the same post.

When resolving this link, it takes you to the original share link except with a share_id=<string> query on the end:
https://www.reddit.com/r/space/comments/15llt1x/two_consecutive_solar_flares_send_potential/?share_id=T-5Gge1AFaeZCVqp2sW_N

Support for using this new link would be helpful.



### Describe alternatives you've considered

Currently, I have had to use requests to follow the new share link in order to get the original link from headers -> location in order to use praw/asyncpraw. 

### Additional context

_No response_

Pull request description:
Add support for new share link
Fixes #1968

## Feature Summary and Justification

This pull request add support for the new share link format created by mobile apps (e.g., https://www.reddit.com/r/redditdev/s/nGnQE1QkLC).


Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index cb824aa5..f655ed87 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -6,10 +6,6 @@ PRAW follows `semantic versioning <https://semver.org/>`_.
 Unreleased
 ----------
 
-**Fixed**
-
-- An issue where submitting a post with media would fail due to an API change.
-
 **Added**
 
 - :meth:`~.SubredditLinkFlairTemplates.reorder` to reorder a subreddit's link flair
@@ -18,6 +14,11 @@ Unreleased
   flair templates.
 - :func:`.stream_generator` now accepts the ``continue_after_id`` parameter, which
   starts the stream after a given item ID.
+- Support for new share URL format created from Reddit's mobile apps.
+
+**Fixed**
+
+- An issue where submitting a post with media would fail due to an API change.
 
 **Changed**
 
diff --git a/praw/models/comment_forest.py b/praw/models/comment_forest.py
index e55334b6..a34f3732 100644
--- a/praw/models/comment_forest.py
+++ b/praw/models/comment_forest.py
@@ -9,7 +9,7 @@ from ..util import _deprecate_args
 from .reddit.more import MoreComments
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class CommentForest:
diff --git a/praw/models/front.py b/praw/models/front.py
index dedbd281..8a5cb2db 100644
--- a/praw/models/front.py
+++ b/praw/models/front.py
@@ -8,7 +8,7 @@ from .listing.generator import ListingGenerator
 from .listing.mixins import SubredditListingMixin
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class Front(SubredditListingMixin):
diff --git a/praw/models/helpers.py b/praw/models/helpers.py
index 9770119c..c562755e 100644
--- a/praw/models/helpers.py
+++ b/praw/models/helpers.py
@@ -12,7 +12,7 @@ from .reddit.live import LiveThread
 from .reddit.multi import Multireddit, Subreddit
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class DraftHelper(PRAWBase):
diff --git a/praw/models/inbox.py b/praw/models/inbox.py
index 84b922f7..b05221dd 100644
--- a/praw/models/inbox.py
+++ b/praw/models/inbox.py
@@ -10,7 +10,7 @@ from .listing.generator import ListingGenerator
 from .util import stream_generator
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class Inbox(PRAWBase):
diff --git a/praw/models/listing/mixins/redditor.py b/praw/models/listing/mixins/redditor.py
index acbf4fca..4c0ac5c9 100644
--- a/praw/models/listing/mixins/redditor.py
+++ b/praw/models/listing/mixins/redditor.py
@@ -10,7 +10,7 @@ from .base import BaseListingMixin
 from .gilded import GildedListingMixin
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class SubListing(BaseListingMixin):
diff --git a/praw/models/listing/mixins/rising.py b/praw/models/listing/mixins/rising.py
index b326cea2..c9848013 100644
--- a/praw/models/listing/mixins/rising.py
+++ b/praw/models/listing/mixins/rising.py
@@ -8,7 +8,7 @@ from ...base import PRAWBase
 from ..generator import ListingGenerator
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class RisingListingMixin(PRAWBase):
diff --git a/praw/models/listing/mixins/submission.py b/praw/models/listing/mixins/submission.py
index 8c7cbdef..468ebf0c 100644
--- a/praw/models/listing/mixins/submission.py
+++ b/praw/models/listing/mixins/submission.py
@@ -8,7 +8,7 @@ from ...base import PRAWBase
 from ..generator import ListingGenerator
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class SubmissionListingMixin(PRAWBase):
diff --git a/praw/models/listing/mixins/subreddit.py b/praw/models/listing/mixins/subreddit.py
index b6014f9c..86bcb205 100644
--- a/praw/models/listing/mixins/subreddit.py
+++ b/praw/models/listing/mixins/subreddit.py
@@ -12,7 +12,7 @@ from .gilded import GildedListingMixin
 from .rising import RisingListingMixin
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class CommentHelper(PRAWBase):
diff --git a/praw/models/mod_action.py b/praw/models/mod_action.py
index 0a02b8ed..74d0d616 100644
--- a/praw/models/mod_action.py
+++ b/praw/models/mod_action.py
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING
 from .base import PRAWBase
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class ModAction(PRAWBase):
diff --git a/praw/models/mod_notes.py b/praw/models/mod_notes.py
index 28662611..01268208 100644
--- a/praw/models/mod_notes.py
+++ b/praw/models/mod_notes.py
@@ -10,7 +10,7 @@ from .reddit.redditor import Redditor
 from .reddit.submission import Submission
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 RedditorType = Union[Redditor, str]
 SubredditType = Union["praw.models.Subreddit", str]
diff --git a/praw/models/reddit/collections.py b/praw/models/reddit/collections.py
index cb5b33e5..23ef7ed9 100644
--- a/praw/models/reddit/collections.py
+++ b/praw/models/reddit/collections.py
@@ -13,7 +13,7 @@ from .submission import Submission
 from .subreddit import Subreddit
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class CollectionModeration(PRAWBase):
diff --git a/praw/models/reddit/comment.py b/praw/models/reddit/comment.py
index 57251be0..4db967b2 100644
--- a/praw/models/reddit/comment.py
+++ b/praw/models/reddit/comment.py
@@ -17,7 +17,7 @@ from .mixins import (
 from .redditor import Redditor
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class Comment(InboxableMixin, UserContentMixin, FullnameMixin, RedditBase):
diff --git a/praw/models/reddit/draft.py b/praw/models/reddit/draft.py
index 28320c6b..4f94d9e5 100644
--- a/praw/models/reddit/draft.py
+++ b/praw/models/reddit/draft.py
@@ -10,7 +10,7 @@ from .subreddit import Subreddit
 from .user_subreddit import UserSubreddit
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class Draft(RedditBase):
diff --git a/praw/models/reddit/live.py b/praw/models/reddit/live.py
index 1f97fea4..6db19281 100644
--- a/praw/models/reddit/live.py
+++ b/praw/models/reddit/live.py
@@ -14,7 +14,7 @@ from .mixins import FullnameMixin
 from .redditor import Redditor
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class LiveContributorRelationship:
diff --git a/praw/models/reddit/message.py b/praw/models/reddit/message.py
index f379025e..9a0b3571 100644
--- a/praw/models/reddit/message.py
+++ b/praw/models/reddit/message.py
@@ -10,7 +10,7 @@ from .redditor import Redditor
 from .subreddit import Subreddit
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class Message(InboxableMixin, ReplyableMixin, FullnameMixin, RedditBase):
diff --git a/praw/models/reddit/mixins/__init__.py b/praw/models/reddit/mixins/__init__.py
index dea1a280..211de63a 100644
--- a/praw/models/reddit/mixins/__init__.py
+++ b/praw/models/reddit/mixins/__init__.py
@@ -19,7 +19,7 @@ from .savable import SavableMixin
 from .votable import VotableMixin
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class ThingModerationMixin(ModNoteMixin):
diff --git a/praw/models/reddit/mixins/editable.py b/praw/models/reddit/mixins/editable.py
index 55fb2a80..35b219c8 100644
--- a/praw/models/reddit/mixins/editable.py
+++ b/praw/models/reddit/mixins/editable.py
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING
 from ....const import API_PATH
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class EditableMixin:
diff --git a/praw/models/reddit/mixins/modnote.py b/praw/models/reddit/mixins/modnote.py
index 505b31d0..2bb5b41a 100644
--- a/praw/models/reddit/mixins/modnote.py
+++ b/praw/models/reddit/mixins/modnote.py
@@ -4,7 +4,7 @@ from __future__ import annotations
 from typing import TYPE_CHECKING, Any, Generator
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class ModNoteMixin:
diff --git a/praw/models/reddit/mixins/replyable.py b/praw/models/reddit/mixins/replyable.py
index 9f475337..0b2aa5b3 100644
--- a/praw/models/reddit/mixins/replyable.py
+++ b/praw/models/reddit/mixins/replyable.py
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING
 from ....const import API_PATH
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class ReplyableMixin:
diff --git a/praw/models/reddit/more.py b/praw/models/reddit/more.py
index f932e973..5a00f213 100644
--- a/praw/models/reddit/more.py
+++ b/praw/models/reddit/more.py
@@ -8,7 +8,7 @@ from ...util import _deprecate_args
 from ..base import PRAWBase
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class MoreComments(PRAWBase):
diff --git a/praw/models/reddit/multi.py b/praw/models/reddit/multi.py
index 19bb0620..e6365f8c 100644
--- a/praw/models/reddit/multi.py
+++ b/praw/models/reddit/multi.py
@@ -13,7 +13,7 @@ from .redditor import Redditor
 from .subreddit import Subreddit, SubredditStream
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class Multireddit(SubredditListingMixin, RedditBase):
diff --git a/praw/models/reddit/redditor.py b/praw/models/reddit/redditor.py
index e4f8b45f..b2190cf0 100644
--- a/praw/models/reddit/redditor.py
+++ b/praw/models/reddit/redditor.py
@@ -13,7 +13,7 @@ from .base import RedditBase
 from .mixins import FullnameMixin, MessageableMixin
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class Redditor(MessageableMixin, RedditorListingMixin, FullnameMixin, RedditBase):
@@ -193,7 +193,7 @@ class Redditor(MessageableMixin, RedditorListingMixin, FullnameMixin, RedditBase
             fullname
         ]["name"]
 
-    def _friend(self, *, data: dict[str:Any], method: str):
+    def _friend(self, *, data: dict[str, Any], method: str):
         url = API_PATH["friend_v1"].format(user=self)
         self._reddit.request(data=dumps(data), method=method, path=url)
 
diff --git a/praw/models/reddit/rules.py b/praw/models/reddit/rules.py
index bdb3794b..281545c8 100644
--- a/praw/models/reddit/rules.py
+++ b/praw/models/reddit/rules.py
@@ -11,7 +11,7 @@ from ...util import _deprecate_args, cachedproperty
 from .base import RedditBase
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class Rule(RedditBase):
diff --git a/praw/models/reddit/submission.py b/praw/models/reddit/submission.py
index dc324e36..345db0a3 100644
--- a/praw/models/reddit/submission.py
+++ b/praw/models/reddit/submission.py
@@ -22,7 +22,7 @@ from .redditor import Redditor
 from .subreddit import Subreddit
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 INLINE_MEDIA_PATTERN = re.compile(
     r"\n\n!?(\[.*?])?\(?((https://((preview|i)\.redd\.it|reddit.com/link).*?)|(?!https)([a-zA-Z0-9]+( \".*?\")?))\)?"
diff --git a/praw/models/reddit/subreddit.py b/praw/models/reddit/subreddit.py
index 32ce4bb0..1613c2f6 100644
--- a/praw/models/reddit/subreddit.py
+++ b/praw/models/reddit/subreddit.py
@@ -42,7 +42,7 @@ from .wikipage import WikiPage
 if TYPE_CHECKING:  # pragma: no cover
     from requests import Response
 
-    import praw.models
+    import praw
 
 
 class Modmail:
diff --git a/praw/models/reddit/user_subreddit.py b/praw/models/reddit/user_subreddit.py
index 9c0ce5af..d99e3b05 100644
--- a/praw/models/reddit/user_subreddit.py
+++ b/praw/models/reddit/user_subreddit.py
@@ -9,7 +9,7 @@ from ...util.cache import cachedproperty
 from .subreddit import Subreddit, SubredditModeration
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class UserSubreddit(Subreddit):
diff --git a/praw/models/reddit/widgets.py b/praw/models/reddit/widgets.py
index 0f5f5fe5..48230580 100644
--- a/praw/models/reddit/widgets.py
+++ b/praw/models/reddit/widgets.py
@@ -12,7 +12,7 @@ from ..base import PRAWBase
 from ..list.base import BaseList
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 WidgetType: TypeVar = TypeVar("WidgetType", bound="Widget")
 
diff --git a/praw/models/reddit/wikipage.py b/praw/models/reddit/wikipage.py
index 7e1b6977..1bb46e89 100644
--- a/praw/models/reddit/wikipage.py
+++ b/praw/models/reddit/wikipage.py
@@ -11,7 +11,7 @@ from .base import RedditBase
 from .redditor import Redditor
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class WikiPageModeration:
diff --git a/praw/models/redditors.py b/praw/models/redditors.py
index 63fe77b8..72548372 100644
--- a/praw/models/redditors.py
+++ b/praw/models/redditors.py
@@ -13,7 +13,7 @@ from .listing.generator import ListingGenerator
 from .util import stream_generator
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class PartialRedditor(SimpleNamespace):
diff --git a/praw/models/subreddits.py b/praw/models/subreddits.py
index bd58d305..e6306fd3 100644
--- a/praw/models/subreddits.py
+++ b/praw/models/subreddits.py
@@ -12,7 +12,7 @@ from .listing.generator import ListingGenerator
 from .util import stream_generator
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class Subreddits(PRAWBase):
diff --git a/praw/models/user.py b/praw/models/user.py
index 33e13444..4ae5d5b9 100644
--- a/praw/models/user.py
+++ b/praw/models/user.py
@@ -17,7 +17,7 @@ from .reddit.redditor import Redditor
 from .reddit.subreddit import Subreddit
 
 if TYPE_CHECKING:  # pragma: no cover
-    import praw.models
+    import praw
 
 
 class User(PRAWBase):
diff --git a/praw/reddit.py b/praw/reddit.py
index 9528d2a2..56812e9e 100644
--- a/praw/reddit.py
+++ b/praw/reddit.py
@@ -9,6 +9,7 @@ import time
 from itertools import islice
 from logging import getLogger
 from typing import IO, TYPE_CHECKING, Any, Generator, Iterable
+from urllib.parse import urlparse
 from warnings import warn
 
 from prawcore import (
@@ -643,6 +644,16 @@ class Reddit:
         self._read_only_core = session(read_only_authorizer)
         self._prepare_common_authorizer(authenticator)
 
+    def _resolve_share_url(self, url: str) -> str:
+        """Return the canonical URL for a given share URL."""
+        parts = urlparse(url).path.rstrip("/").split("/")
+        if "s" in parts:  # handling new share urls from mobile apps
+            try:
+                self.get(url)
+            except Redirect as e:
+                return e.response.next.url
+        return url
+
     @_deprecate_args("id", "url")
     def comment(
         self, id: str | None = None, *, url: str | None = None
@@ -658,6 +669,8 @@ class Reddit:
             :meth:`~.Comment.refresh` on the returned :class:`.Comment`.
 
         """
+        if url:
+            url = self._resolve_share_url(url)
         return models.Comment(self, id=id, url=url)
 
     @_deprecate_args("path", "data", "json", "params")
@@ -977,6 +990,8 @@ class Reddit:
         Either ``id`` or ``url`` can be provided, but not both.
 
         """
+        if url:
+            url = self._resolve_share_url(url)
         return models.Submission(self, id=id, url=url)
 
     def username_available(self, name: str) -> bool:


Test patch:
diff --git a/tests/integration/cassettes/TestComment.test_resolve_from_share_url.json b/tests/integration/cassettes/TestComment.test_resolve_from_share_url.json
new file mode 100644
index 00000000..8a42673a
--- /dev/null
+++ b/tests/integration/cassettes/TestComment.test_resolve_from_share_url.json
@@ -0,0 +1,198 @@
+{
+  "http_interactions": [
+    {
+      "recorded_at": "2023-11-09T19:03:42",
+      "request": {
+        "body": {
+          "encoding": "utf-8",
+          "string": "grant_type=client_credentials"
+        },
+        "headers": {
+          "Accept": [
+            "*/*"
+          ],
+          "Accept-Encoding": [
+            "identity"
+          ],
+          "Authorization": [
+            "Basic <BASIC_AUTH>"
+          ],
+          "Connection": [
+            "close"
+          ],
+          "Content-Length": [
+            "29"
+          ],
+          "Content-Type": [
+            "application/x-www-form-urlencoded"
+          ],
+          "User-Agent": [
+            "<USER_AGENT> PRAW/7.7.2.dev0 prawcore/2.3.0"
+          ]
+        },
+        "method": "POST",
+        "uri": "https://www.reddit.com/api/v1/access_token"
+      },
+      "response": {
+        "body": {
+          "encoding": "UTF-8",
+          "string": "{\"access_token\": \"<ACCESS_TOKEN>\", \"token_type\": \"bearer\", \"expires_in\": 86400, \"scope\": \"*\"}"
+        },
+        "headers": {
+          "Accept-Ranges": [
+            "bytes"
+          ],
+          "Cache-Control": [
+            "private, max-age=3600"
+          ],
+          "Connection": [
+            "close"
+          ],
+          "Content-Length": [
+            "812"
+          ],
+          "Date": [
+            "Thu, 09 Nov 2023 19:03:42 GMT"
+          ],
+          "NEL": [
+            "{\"report_to\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": false, \"success_fraction\": 1.0, \"failure_fraction\": 1.0}"
+          ],
+          "Report-To": [
+            "{\"group\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": true,  \"endpoints\": [{ \"url\": \"https://w3-reporting-nel.reddit.com/reports\" }]}, {\"group\": \"w3-reporting\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting.reddit.com/reports\" }]}, {\"group\": \"w3-reporting-csp\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting-csp.reddit.com/reports\" }]}"
+          ],
+          "Server": [
+            "snooserv"
+          ],
+          "Set-Cookie": [
+            "edgebucket=ZiuasF2t2VM3rHunbP; Domain=reddit.com; Max-Age=63071999; Path=/;  secure"
+          ],
+          "Strict-Transport-Security": [
+            "max-age=31536000; includeSubdomains"
+          ],
+          "Vary": [
+            "accept-encoding, Accept-Encoding"
+          ],
+          "Via": [
+            "1.1 varnish"
+          ],
+          "X-Content-Type-Options": [
+            "nosniff"
+          ],
+          "X-Frame-Options": [
+            "SAMEORIGIN"
+          ],
+          "X-XSS-Protection": [
+            "1; mode=block"
+          ],
+          "content-type": [
+            "application/json; charset=UTF-8"
+          ],
+          "x-reddit-loid": [
+            "000000000njwzxoaiz.2.1699556622239.Z0FBQUFBQmxUUzBPZm1TOUx4SElwWW1rMG1rSXhZdmRCb2REMm50Vlo3V2xyaUltbnpKZTM4ZVd2cmNmdHRHbktzazFwS2FUNzIxeW5HTmN3MVIxM084NERFdnNHd2RaY2RFTlg1dHBmVFJqQjdBYVZuV1RHRGpzZjk5S3RBcG5laDE1ZFA2WF9vSmc"
+          ]
+        },
+        "status": {
+          "code": 200,
+          "message": "OK"
+        },
+        "url": "https://www.reddit.com/api/v1/access_token"
+      }
+    },
+    {
+      "recorded_at": "2023-11-09T19:03:42",
+      "request": {
+        "body": {
+          "encoding": "utf-8",
+          "string": ""
+        },
+        "headers": {
+          "Accept": [
+            "*/*"
+          ],
+          "Accept-Encoding": [
+            "identity"
+          ],
+          "Authorization": [
+            "bearer <ACCESS_TOKEN>"
+          ],
+          "Connection": [
+            "keep-alive"
+          ],
+          "Cookie": [
+            "edgebucket=ZiuasF2t2VM3rHunbP"
+          ],
+          "User-Agent": [
+            "<USER_AGENT> PRAW/7.7.2.dev0 prawcore/2.3.0"
+          ]
+        },
+        "method": "GET",
+        "uri": "https://www.reddit.com/r/redditdev/s/nGnQE1QkLC?raw_json=1"
+      },
+      "response": {
+        "body": {
+          "encoding": "utf-8",
+          "string": "<a href=\"https://www.reddit.com/r/redditdev/comments/2gmzqe/praw_https_enabled_praw_testing_needed/cklhv0f/?context=3&amp;share_id=vi8DOF9B0U5cJSzhFjDE9&amp;utm_content=1&amp;utm_medium=ios_app&amp;utm_name=ioscss&amp;utm_source=share&amp;utm_term=1\">Moved Permanently</a>.\n\n"
+        },
+        "headers": {
+          "Accept-Ranges": [
+            "bytes"
+          ],
+          "Cache-Control": [
+            "private, max-age=3600"
+          ],
+          "Connection": [
+            "keep-alive"
+          ],
+          "Content-Length": [
+            "275"
+          ],
+          "Date": [
+            "Thu, 09 Nov 2023 19:03:42 GMT"
+          ],
+          "NEL": [
+            "{\"report_to\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": false, \"success_fraction\": 1.0, \"failure_fraction\": 1.0}"
+          ],
+          "Report-To": [
+            "{\"group\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": true,  \"endpoints\": [{ \"url\": \"https://w3-reporting-nel.reddit.com/reports\" }]}, {\"group\": \"w3-reporting\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting.reddit.com/reports\" }]}, {\"group\": \"w3-reporting-csp\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting-csp.reddit.com/reports\" }]}"
+          ],
+          "Server": [
+            "snooserv"
+          ],
+          "Set-Cookie": [
+            "csv=2; Max-Age=63072000; Domain=.reddit.com; Path=/; Secure; SameSite=None"
+          ],
+          "Strict-Transport-Security": [
+            "max-age=31536000; includeSubdomains"
+          ],
+          "Vary": [
+            "Accept-Encoding"
+          ],
+          "Via": [
+            "1.1 varnish"
+          ],
+          "X-Content-Type-Options": [
+            "nosniff"
+          ],
+          "X-Frame-Options": [
+            "SAMEORIGIN"
+          ],
+          "X-XSS-Protection": [
+            "1; mode=block"
+          ],
+          "content-type": [
+            "text/html; charset=utf-8"
+          ],
+          "location": [
+            "https://www.reddit.com/r/redditdev/comments/2gmzqe/praw_https_enabled_praw_testing_needed/cklhv0f/?context=3&share_id=vi8DOF9B0U5cJSzhFjDE9&utm_content=1&utm_medium=ios_app&utm_name=ioscss&utm_source=share&utm_term=1"
+          ]
+        },
+        "status": {
+          "code": 301,
+          "message": "Moved Permanently"
+        },
+        "url": "https://www.reddit.com/r/redditdev/s/nGnQE1QkLC?raw_json=1"
+      }
+    }
+  ],
+  "recorded_with": "betamax/0.8.1"
+}
diff --git a/tests/integration/cassettes/TestComment.test_resolve_from_share_url__invalid_url.json b/tests/integration/cassettes/TestComment.test_resolve_from_share_url__invalid_url.json
new file mode 100644
index 00000000..924e0900
--- /dev/null
+++ b/tests/integration/cassettes/TestComment.test_resolve_from_share_url__invalid_url.json
@@ -0,0 +1,201 @@
+{
+  "http_interactions": [
+    {
+      "recorded_at": "2023-11-09T19:04:16",
+      "request": {
+        "body": {
+          "encoding": "utf-8",
+          "string": "grant_type=client_credentials"
+        },
+        "headers": {
+          "Accept": [
+            "*/*"
+          ],
+          "Accept-Encoding": [
+            "identity"
+          ],
+          "Authorization": [
+            "Basic <BASIC_AUTH>"
+          ],
+          "Connection": [
+            "close"
+          ],
+          "Content-Length": [
+            "29"
+          ],
+          "Content-Type": [
+            "application/x-www-form-urlencoded"
+          ],
+          "User-Agent": [
+            "<USER_AGENT> PRAW/7.7.2.dev0 prawcore/2.3.0"
+          ]
+        },
+        "method": "POST",
+        "uri": "https://www.reddit.com/api/v1/access_token"
+      },
+      "response": {
+        "body": {
+          "encoding": "UTF-8",
+          "string": "{\"access_token\": \"<ACCESS_TOKEN>\", \"token_type\": \"bearer\", \"expires_in\": 86400, \"scope\": \"*\"}"
+        },
+        "headers": {
+          "Accept-Ranges": [
+            "bytes"
+          ],
+          "Cache-Control": [
+            "private, max-age=3600"
+          ],
+          "Connection": [
+            "close"
+          ],
+          "Content-Length": [
+            "812"
+          ],
+          "Date": [
+            "Thu, 09 Nov 2023 19:04:16 GMT"
+          ],
+          "NEL": [
+            "{\"report_to\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": false, \"success_fraction\": 1.0, \"failure_fraction\": 1.0}"
+          ],
+          "Report-To": [
+            "{\"group\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": true,  \"endpoints\": [{ \"url\": \"https://w3-reporting-nel.reddit.com/reports\" }]}, {\"group\": \"w3-reporting\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting.reddit.com/reports\" }]}, {\"group\": \"w3-reporting-csp\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting-csp.reddit.com/reports\" }]}"
+          ],
+          "Server": [
+            "snooserv"
+          ],
+          "Set-Cookie": [
+            "edgebucket=ji5mkxOqhmGDRBCHje; Domain=reddit.com; Max-Age=63071999; Path=/;  secure"
+          ],
+          "Strict-Transport-Security": [
+            "max-age=31536000; includeSubdomains"
+          ],
+          "Vary": [
+            "accept-encoding"
+          ],
+          "Via": [
+            "1.1 varnish"
+          ],
+          "X-Content-Type-Options": [
+            "nosniff"
+          ],
+          "X-Frame-Options": [
+            "SAMEORIGIN"
+          ],
+          "X-XSS-Protection": [
+            "1; mode=block"
+          ],
+          "content-type": [
+            "application/json; charset=UTF-8"
+          ],
+          "x-moose": [
+            "majestic"
+          ],
+          "x-reddit-loid": [
+            "000000000njx1ov2vf.2.1699556656453.Z0FBQUFBQmxUUzB3dEFGY2lCVGlGLTFDbElQd1QweUhMazBJQVNGS2o2eVpZTFJ6ZG9aZEZTTjBNYnB4Wjl0NFFlek5JM1U3M1AzZnB5dFJDaWVSbEd5SEFBLWxOX21NSFpuVjZOTnBablVicENYVEdxYmhHYVlkWVBQQUhhX01uLXM3Y3k4QTY4UEY"
+          ]
+        },
+        "status": {
+          "code": 200,
+          "message": "OK"
+        },
+        "url": "https://www.reddit.com/api/v1/access_token"
+      }
+    },
+    {
+      "recorded_at": "2023-11-09T19:04:16",
+      "request": {
+        "body": {
+          "encoding": "utf-8",
+          "string": ""
+        },
+        "headers": {
+          "Accept": [
+            "*/*"
+          ],
+          "Accept-Encoding": [
+            "identity"
+          ],
+          "Authorization": [
+            "bearer <ACCESS_TOKEN>"
+          ],
+          "Connection": [
+            "keep-alive"
+          ],
+          "Cookie": [
+            "edgebucket=ji5mkxOqhmGDRBCHje"
+          ],
+          "User-Agent": [
+            "<USER_AGENT> PRAW/7.7.2.dev0 prawcore/2.3.0"
+          ]
+        },
+        "method": "GET",
+        "uri": "https://www.reddit.com/r/redditdev/s/WNauetbiNG?raw_json=1"
+      },
+      "response": {
+        "body": {
+          "encoding": "utf-8",
+          "string": "<a href=\"https://www.reddit.com/r/redditdev/comments/2gmzqe/praw_https_enabled_praw_testing_needed/?share_id=oqqXWtvgcCuonkcpck8yD&amp;utm_content=1&amp;utm_medium=ios_app&amp;utm_name=ioscss&amp;utm_source=share&amp;utm_term=1\">Moved Permanently</a>.\n\n"
+        },
+        "headers": {
+          "Accept-Ranges": [
+            "bytes"
+          ],
+          "Cache-Control": [
+            "private, max-age=3600"
+          ],
+          "Connection": [
+            "keep-alive"
+          ],
+          "Content-Length": [
+            "253"
+          ],
+          "Date": [
+            "Thu, 09 Nov 2023 19:04:16 GMT"
+          ],
+          "NEL": [
+            "{\"report_to\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": false, \"success_fraction\": 1.0, \"failure_fraction\": 1.0}"
+          ],
+          "Report-To": [
+            "{\"group\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": true,  \"endpoints\": [{ \"url\": \"https://w3-reporting-nel.reddit.com/reports\" }]}, {\"group\": \"w3-reporting\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting.reddit.com/reports\" }]}, {\"group\": \"w3-reporting-csp\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting-csp.reddit.com/reports\" }]}"
+          ],
+          "Server": [
+            "snooserv"
+          ],
+          "Set-Cookie": [
+            "csv=2; Max-Age=63072000; Domain=.reddit.com; Path=/; Secure; SameSite=None"
+          ],
+          "Strict-Transport-Security": [
+            "max-age=31536000; includeSubdomains"
+          ],
+          "Vary": [
+            "Accept-Encoding"
+          ],
+          "Via": [
+            "1.1 varnish"
+          ],
+          "X-Content-Type-Options": [
+            "nosniff"
+          ],
+          "X-Frame-Options": [
+            "SAMEORIGIN"
+          ],
+          "X-XSS-Protection": [
+            "1; mode=block"
+          ],
+          "content-type": [
+            "text/html; charset=utf-8"
+          ],
+          "location": [
+            "https://www.reddit.com/r/redditdev/comments/2gmzqe/praw_https_enabled_praw_testing_needed/?share_id=oqqXWtvgcCuonkcpck8yD&utm_content=1&utm_medium=ios_app&utm_name=ioscss&utm_source=share&utm_term=1"
+          ]
+        },
+        "status": {
+          "code": 301,
+          "message": "Moved Permanently"
+        },
+        "url": "https://www.reddit.com/r/redditdev/s/WNauetbiNG?raw_json=1"
+      }
+    }
+  ],
+  "recorded_with": "betamax/0.8.1"
+}
diff --git a/tests/integration/cassettes/TestSubmission.test_resolve_from_share_url.json b/tests/integration/cassettes/TestSubmission.test_resolve_from_share_url.json
new file mode 100644
index 00000000..0b4046c4
--- /dev/null
+++ b/tests/integration/cassettes/TestSubmission.test_resolve_from_share_url.json
@@ -0,0 +1,201 @@
+{
+  "http_interactions": [
+    {
+      "recorded_at": "2023-11-09T19:05:44",
+      "request": {
+        "body": {
+          "encoding": "utf-8",
+          "string": "grant_type=client_credentials"
+        },
+        "headers": {
+          "Accept": [
+            "*/*"
+          ],
+          "Accept-Encoding": [
+            "identity"
+          ],
+          "Authorization": [
+            "Basic <BASIC_AUTH>"
+          ],
+          "Connection": [
+            "close"
+          ],
+          "Content-Length": [
+            "29"
+          ],
+          "Content-Type": [
+            "application/x-www-form-urlencoded"
+          ],
+          "User-Agent": [
+            "<USER_AGENT> PRAW/7.7.2.dev0 prawcore/2.3.0"
+          ]
+        },
+        "method": "POST",
+        "uri": "https://www.reddit.com/api/v1/access_token"
+      },
+      "response": {
+        "body": {
+          "encoding": "UTF-8",
+          "string": "{\"access_token\": \"<ACCESS_TOKEN>\", \"token_type\": \"bearer\", \"expires_in\": 86400, \"scope\": \"*\"}"
+        },
+        "headers": {
+          "Accept-Ranges": [
+            "bytes"
+          ],
+          "Cache-Control": [
+            "private, max-age=3600"
+          ],
+          "Connection": [
+            "close"
+          ],
+          "Content-Length": [
+            "812"
+          ],
+          "Date": [
+            "Thu, 09 Nov 2023 19:05:44 GMT"
+          ],
+          "NEL": [
+            "{\"report_to\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": false, \"success_fraction\": 1.0, \"failure_fraction\": 1.0}"
+          ],
+          "Report-To": [
+            "{\"group\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": true,  \"endpoints\": [{ \"url\": \"https://w3-reporting-nel.reddit.com/reports\" }]}, {\"group\": \"w3-reporting\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting.reddit.com/reports\" }]}, {\"group\": \"w3-reporting-csp\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting-csp.reddit.com/reports\" }]}"
+          ],
+          "Server": [
+            "snooserv"
+          ],
+          "Set-Cookie": [
+            "edgebucket=y9MIAbKPXg1UCtEUjS; Domain=reddit.com; Max-Age=63071999; Path=/;  secure"
+          ],
+          "Strict-Transport-Security": [
+            "max-age=31536000; includeSubdomains"
+          ],
+          "Vary": [
+            "accept-encoding"
+          ],
+          "Via": [
+            "1.1 varnish"
+          ],
+          "X-Content-Type-Options": [
+            "nosniff"
+          ],
+          "X-Frame-Options": [
+            "SAMEORIGIN"
+          ],
+          "X-XSS-Protection": [
+            "1; mode=block"
+          ],
+          "content-type": [
+            "application/json; charset=UTF-8"
+          ],
+          "x-moose": [
+            "majestic"
+          ],
+          "x-reddit-loid": [
+            "000000000njx4eypn1.2.1699556744224.Z0FBQUFBQmxUUzJJOWdUclR5d1hvZ0N5ak0xbUkyZmVYbVNadlFjYlFXVkRoaXgxeGo1cEFmSHNtcERLQ21JOUFQZkx1R1d1ZnFkTnRKSUducFNIUFhXdnZTVEVqTjJSTGdBNGdRRTREMVVZS1NvOTdwY29KLTdyeVYySWl0anJsS1FOcDFldWszS2M"
+          ]
+        },
+        "status": {
+          "code": 200,
+          "message": "OK"
+        },
+        "url": "https://www.reddit.com/api/v1/access_token"
+      }
+    },
+    {
+      "recorded_at": "2023-11-09T19:05:44",
+      "request": {
+        "body": {
+          "encoding": "utf-8",
+          "string": ""
+        },
+        "headers": {
+          "Accept": [
+            "*/*"
+          ],
+          "Accept-Encoding": [
+            "identity"
+          ],
+          "Authorization": [
+            "bearer <ACCESS_TOKEN>"
+          ],
+          "Connection": [
+            "keep-alive"
+          ],
+          "Cookie": [
+            "edgebucket=y9MIAbKPXg1UCtEUjS"
+          ],
+          "User-Agent": [
+            "<USER_AGENT> PRAW/7.7.2.dev0 prawcore/2.3.0"
+          ]
+        },
+        "method": "GET",
+        "uri": "https://www.reddit.com/r/redditdev/s/WNauetbiNG?raw_json=1"
+      },
+      "response": {
+        "body": {
+          "encoding": "utf-8",
+          "string": "<a href=\"https://www.reddit.com/r/redditdev/comments/2gmzqe/praw_https_enabled_praw_testing_needed/?share_id=oqqXWtvgcCuonkcpck8yD&amp;utm_content=1&amp;utm_medium=ios_app&amp;utm_name=ioscss&amp;utm_source=share&amp;utm_term=1\">Moved Permanently</a>.\n\n"
+        },
+        "headers": {
+          "Accept-Ranges": [
+            "bytes"
+          ],
+          "Cache-Control": [
+            "private, max-age=3600"
+          ],
+          "Connection": [
+            "keep-alive"
+          ],
+          "Content-Length": [
+            "253"
+          ],
+          "Date": [
+            "Thu, 09 Nov 2023 19:05:44 GMT"
+          ],
+          "NEL": [
+            "{\"report_to\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": false, \"success_fraction\": 1.0, \"failure_fraction\": 1.0}"
+          ],
+          "Report-To": [
+            "{\"group\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": true,  \"endpoints\": [{ \"url\": \"https://w3-reporting-nel.reddit.com/reports\" }]}, {\"group\": \"w3-reporting\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting.reddit.com/reports\" }]}, {\"group\": \"w3-reporting-csp\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting-csp.reddit.com/reports\" }]}"
+          ],
+          "Server": [
+            "snooserv"
+          ],
+          "Set-Cookie": [
+            "csv=2; Max-Age=63072000; Domain=.reddit.com; Path=/; Secure; SameSite=None"
+          ],
+          "Strict-Transport-Security": [
+            "max-age=31536000; includeSubdomains"
+          ],
+          "Vary": [
+            "Accept-Encoding"
+          ],
+          "Via": [
+            "1.1 varnish"
+          ],
+          "X-Content-Type-Options": [
+            "nosniff"
+          ],
+          "X-Frame-Options": [
+            "SAMEORIGIN"
+          ],
+          "X-XSS-Protection": [
+            "1; mode=block"
+          ],
+          "content-type": [
+            "text/html; charset=utf-8"
+          ],
+          "location": [
+            "https://www.reddit.com/r/redditdev/comments/2gmzqe/praw_https_enabled_praw_testing_needed/?share_id=oqqXWtvgcCuonkcpck8yD&utm_content=1&utm_medium=ios_app&utm_name=ioscss&utm_source=share&utm_term=1"
+          ]
+        },
+        "status": {
+          "code": 301,
+          "message": "Moved Permanently"
+        },
+        "url": "https://www.reddit.com/r/redditdev/s/WNauetbiNG?raw_json=1"
+      }
+    }
+  ],
+  "recorded_with": "betamax/0.8.1"
+}
diff --git a/tests/integration/cassettes/TestSubmission.test_resolve_from_share_url__invalid_url.json b/tests/integration/cassettes/TestSubmission.test_resolve_from_share_url__invalid_url.json
new file mode 100644
index 00000000..758b3257
--- /dev/null
+++ b/tests/integration/cassettes/TestSubmission.test_resolve_from_share_url__invalid_url.json
@@ -0,0 +1,195 @@
+{
+  "http_interactions": [
+    {
+      "recorded_at": "2023-11-09T19:06:53",
+      "request": {
+        "body": {
+          "encoding": "utf-8",
+          "string": "grant_type=client_credentials"
+        },
+        "headers": {
+          "Accept": [
+            "*/*"
+          ],
+          "Accept-Encoding": [
+            "identity"
+          ],
+          "Authorization": [
+            "Basic <BASIC_AUTH>"
+          ],
+          "Connection": [
+            "close"
+          ],
+          "Content-Length": [
+            "29"
+          ],
+          "Content-Type": [
+            "application/x-www-form-urlencoded"
+          ],
+          "User-Agent": [
+            "<USER_AGENT> PRAW/7.7.2.dev0 prawcore/2.3.0"
+          ]
+        },
+        "method": "POST",
+        "uri": "https://www.reddit.com/api/v1/access_token"
+      },
+      "response": {
+        "body": {
+          "encoding": "UTF-8",
+          "string": "{\"access_token\": \"<ACCESS_TOKEN>\", \"token_type\": \"bearer\", \"expires_in\": 86400, \"scope\": \"*\"}"
+        },
+        "headers": {
+          "Accept-Ranges": [
+            "bytes"
+          ],
+          "Cache-Control": [
+            "private, max-age=3600"
+          ],
+          "Connection": [
+            "close"
+          ],
+          "Content-Length": [
+            "812"
+          ],
+          "Date": [
+            "Thu, 09 Nov 2023 19:06:54 GMT"
+          ],
+          "NEL": [
+            "{\"report_to\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": false, \"success_fraction\": 1.0, \"failure_fraction\": 1.0}"
+          ],
+          "Report-To": [
+            "{\"group\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": true,  \"endpoints\": [{ \"url\": \"https://w3-reporting-nel.reddit.com/reports\" }]}, {\"group\": \"w3-reporting\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting.reddit.com/reports\" }]}, {\"group\": \"w3-reporting-csp\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting-csp.reddit.com/reports\" }]}"
+          ],
+          "Server": [
+            "snooserv"
+          ],
+          "Set-Cookie": [
+            "edgebucket=YuaQkSYe7CLjd5kM7H; Domain=reddit.com; Max-Age=63071999; Path=/;  secure"
+          ],
+          "Strict-Transport-Security": [
+            "max-age=31536000; includeSubdomains"
+          ],
+          "Vary": [
+            "accept-encoding"
+          ],
+          "Via": [
+            "1.1 varnish"
+          ],
+          "X-Content-Type-Options": [
+            "nosniff"
+          ],
+          "X-Frame-Options": [
+            "SAMEORIGIN"
+          ],
+          "X-XSS-Protection": [
+            "1; mode=block"
+          ],
+          "content-type": [
+            "application/json; charset=UTF-8"
+          ],
+          "x-moose": [
+            "majestic"
+          ],
+          "x-reddit-loid": [
+            "000000000njx6srhai.2.1699556814022.Z0FBQUFBQmxUUzNPRVdfX0p6V090eVlJYURGUFNORV9mODZpZWRRSmZybjV2ZjgwenZYNEpPQTN3VEdGQlRZbjhLM1I3clR4VkhkNkthQXY1dVdjeVZmVXB3NmRsM1RNOThUWlRldzQtY2JwV29WNTJIbktrT1lTMEpTMTEyelZocnNWM1JmNExBRGQ"
+          ]
+        },
+        "status": {
+          "code": 200,
+          "message": "OK"
+        },
+        "url": "https://www.reddit.com/api/v1/access_token"
+      }
+    },
+    {
+      "recorded_at": "2023-11-09T19:06:53",
+      "request": {
+        "body": {
+          "encoding": "utf-8",
+          "string": ""
+        },
+        "headers": {
+          "Accept": [
+            "*/*"
+          ],
+          "Accept-Encoding": [
+            "identity"
+          ],
+          "Authorization": [
+            "bearer <ACCESS_TOKEN>"
+          ],
+          "Connection": [
+            "keep-alive"
+          ],
+          "Cookie": [
+            "edgebucket=YuaQkSYe7CLjd5kM7H"
+          ],
+          "User-Agent": [
+            "<USER_AGENT> PRAW/7.7.2.dev0 prawcore/2.3.0"
+          ]
+        },
+        "method": "GET",
+        "uri": "https://reddit.com/r/space/s/?raw_json=1"
+      },
+      "response": {
+        "body": {
+          "encoding": null,
+          "string": ""
+        },
+        "headers": {
+          "Accept-Ranges": [
+            "bytes"
+          ],
+          "Cache-Control": [
+            "private, max-age=3600"
+          ],
+          "Connection": [
+            "close"
+          ],
+          "Content-Length": [
+            "0"
+          ],
+          "Date": [
+            "Thu, 09 Nov 2023 19:06:54 GMT"
+          ],
+          "Location": [
+            "https://www.reddit.com/r/space/s/?raw_json=1"
+          ],
+          "NEL": [
+            "{\"report_to\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": false, \"success_fraction\": 1.0, \"failure_fraction\": 1.0}"
+          ],
+          "Report-To": [
+            "{\"group\": \"w3-reporting-nel\", \"max_age\": 14400, \"include_subdomains\": true,  \"endpoints\": [{ \"url\": \"https://w3-reporting-nel.reddit.com/reports\" }]}, {\"group\": \"w3-reporting\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting.reddit.com/reports\" }]}, {\"group\": \"w3-reporting-csp\", \"max_age\": 14400, \"include_subdomains\": true, \"endpoints\": [{ \"url\": \"https://w3-reporting-csp.reddit.com/reports\" }]}"
+          ],
+          "Retry-After": [
+            "0"
+          ],
+          "Server": [
+            "snooserv"
+          ],
+          "Strict-Transport-Security": [
+            "max-age=31536000; includeSubdomains; preload"
+          ],
+          "Via": [
+            "1.1 varnish"
+          ],
+          "X-Content-Type-Options": [
+            "nosniff"
+          ],
+          "X-Frame-Options": [
+            "SAMEORIGIN"
+          ],
+          "X-XSS-Protection": [
+            "1; mode=block"
+          ]
+        },
+        "status": {
+          "code": 301,
+          "message": "Moved Permanently"
+        },
+        "url": "https://reddit.com/r/space/s/?raw_json=1"
+      }
+    }
+  ],
+  "recorded_with": "betamax/0.8.1"
+}
diff --git a/tests/integration/models/reddit/test_comment.py b/tests/integration/models/reddit/test_comment.py
index 9b21af6d..ba721703 100644
--- a/tests/integration/models/reddit/test_comment.py
+++ b/tests/integration/models/reddit/test_comment.py
@@ -217,6 +217,15 @@ class TestComment(IntegrationTest):
         reddit.read_only = False
         Comment(reddit, "d0335z3").report("custom")
 
+    def test_resolve_from_share_url(self, reddit):
+        url = "https://www.reddit.com/r/redditdev/s/nGnQE1QkLC"
+        assert reddit.comment(url=url) == "cklhv0f", url
+
+    def test_resolve_from_share_url__invalid_url(self, reddit):
+        url = "https://www.reddit.com/r/redditdev/s/WNauetbiNG"
+        with pytest.raises(ClientException):
+            reddit.comment(url=url)
+
     def test_save(self, reddit):
         reddit.read_only = False
         Comment(reddit, "d1680wu").save(category="foo")
diff --git a/tests/integration/models/reddit/test_submission.py b/tests/integration/models/reddit/test_submission.py
index 81abd61f..4743c6bd 100644
--- a/tests/integration/models/reddit/test_submission.py
+++ b/tests/integration/models/reddit/test_submission.py
@@ -1,6 +1,6 @@
 import pytest
 
-from praw.exceptions import RedditAPIException
+from praw.exceptions import RedditAPIException, ClientException
 from praw.models import Comment, InlineGif, InlineImage, InlineVideo, Submission
 
 from ... import IntegrationTest
@@ -276,6 +276,15 @@ class TestSubmission(IntegrationTest):
         reddit.read_only = False
         Submission(reddit, "4b536h").report("praw")
 
+    def test_resolve_from_share_url(self, reddit):
+        url = "https://www.reddit.com/r/redditdev/s/WNauetbiNG"
+        assert reddit.submission(url=url) == "2gmzqe", url
+
+    def test_resolve_from_share_url__invalid_url(self, reddit):
+        url = "https://reddit.com/r/space/s/"
+        with pytest.raises(ClientException):
+            reddit.submission(url=url)
+
     def test_save(self, reddit):
         reddit.read_only = False
         Submission(reddit, "4b536p").save()