Repository: praw-dev/praw

Issue:
Add `Subreddit.rules`
See https://github.com/praw-dev/praw/pull/612 for the PRAW 3.6 addition.

@leviroth any chance you want to re-add this for PRAW4?


Discussion:
Funny, I had just noticed that wasn't in PRAW4. Would be glad to do that.

Resolving patch:
diff --git a/praw/const.py b/praw/const.py
--- a/praw/const.py
+++ b/praw/const.py
@@ -83,6 +83,7 @@
     'read_message':           'api/read_message/',
     'remove':                 'api/remove/',
     'report':                 'api/report/',
+    'rules':                  'r/{subreddit}/about/rules',
     'save':                   'api/save/',
     'search':                 'r/{subreddit}/search/',
     'select_flair':           'r/{subreddit}/api/selectflair/',
diff --git a/praw/models/reddit/subreddit.py b/praw/models/reddit/subreddit.py
--- a/praw/models/reddit/subreddit.py
+++ b/praw/models/reddit/subreddit.py
@@ -248,6 +248,10 @@ def random(self):
         return self._submission_class(self._reddit, url=urljoin(
             self._reddit.config.reddit_url, path))
 
+    def rules(self):
+        """Return rules for the subreddit."""
+        return self._reddit.get(API_PATH['rules'].format(subreddit=self))
+
     def search(self, query, sort='relevance', syntax='cloudsearch',
                time_filter='all', **generator_kwargs):
         """Return a ListingGenerator for items that match ``query``.


Test patch:
diff --git a/tests/integration/cassettes/TestSubreddit.test_rules.json b/tests/integration/cassettes/TestSubreddit.test_rules.json
new file mode 100644
--- /dev/null
+++ b/tests/integration/cassettes/TestSubreddit.test_rules.json
@@ -0,0 +1,109 @@
+{
+  "http_interactions": [
+    {
+      "recorded_at": "2016-12-29T01:38:30",
+      "request": {
+        "body": {
+          "encoding": "utf-8",
+          "string": "grant_type=client_credentials"
+        },
+        "headers": {
+          "Accept": "*/*",
+          "Accept-Encoding": "identity",
+          "Authorization": "Basic <BASIC_AUTH>",
+          "Connection": "keep-alive",
+          "Content-Length": "29",
+          "Content-Type": "application/x-www-form-urlencoded",
+          "User-Agent": "<USER_AGENT> PRAW/4.2.0dev0 prawcore/0.6.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\": 3600, \"scope\": \"*\"}"
+        },
+        "headers": {
+          "Accept-Ranges": "bytes",
+          "Connection": "keep-alive",
+          "Content-Length": "105",
+          "Content-Type": "application/json; charset=UTF-8",
+          "Date": "Thu, 29 Dec 2016 01:38:31 GMT",
+          "Server": "snooserv",
+          "Set-Cookie": "loid=v0RWuVRxcgEA6qBFWO; Domain=reddit.com; Max-Age=63071999; Path=/;  secure",
+          "Strict-Transport-Security": "max-age=15552000; includeSubDomains; preload",
+          "Via": "1.1 varnish",
+          "X-Cache": "MISS",
+          "X-Cache-Hits": "0",
+          "X-Moose": "majestic",
+          "X-Served-By": "cache-ord1739-ORD",
+          "X-Timer": "S1482975511.910025,VS0,VE33",
+          "cache-control": "max-age=0, must-revalidate",
+          "x-content-type-options": "nosniff",
+          "x-frame-options": "SAMEORIGIN",
+          "x-xss-protection": "1; mode=block"
+        },
+        "status": {
+          "code": 200,
+          "message": "OK"
+        },
+        "url": "https://www.reddit.com/api/v1/access_token"
+      }
+    },
+    {
+      "recorded_at": "2016-12-29T01:38:30",
+      "request": {
+        "body": {
+          "encoding": "utf-8",
+          "string": ""
+        },
+        "headers": {
+          "Accept": "*/*",
+          "Accept-Encoding": "identity",
+          "Authorization": "bearer <ACCESS_TOKEN>",
+          "Connection": "keep-alive",
+          "Cookie": "loid=v0RWuVRxcgEA6qBFWO; loidcreated=1482975511000",
+          "User-Agent": "<USER_AGENT> PRAW/4.2.0dev0 prawcore/0.6.0"
+        },
+        "method": "GET",
+        "uri": "https://oauth.reddit.com/r/<TEST_SUBREDDIT>/about/rules?raw_json=1"
+      },
+      "response": {
+        "body": {
+          "encoding": "UTF-8",
+          "string": "{\"rules\": [{\"kind\": \"all\", \"description\": \"Sample rule\", \"short_name\": \"Sample rule\", \"created_utc\": 1465639064.0, \"priority\": 0, \"description_html\": \"\\u003C!-- SC_OFF --\\u003E\\u003Cdiv class=\\\"md\\\"\\u003E\\u003Cp\\u003ESample rule\\u003C/p\\u003E\\n\\u003C/div\\u003E\\u003C!-- SC_ON --\\u003E\"}], \"site_rules\": [\"Spam\", \"Personal and confidential information\", \"Threatening, harassing, or inciting violence\"]}"
+        },
+        "headers": {
+          "Accept-Ranges": "bytes",
+          "Connection": "keep-alive",
+          "Content-Length": "401",
+          "Content-Type": "application/json; charset=UTF-8",
+          "Date": "Thu, 29 Dec 2016 01:38:32 GMT",
+          "Server": "snooserv",
+          "Strict-Transport-Security": "max-age=15552000; includeSubDomains; preload",
+          "Via": "1.1 varnish",
+          "X-Cache": "MISS",
+          "X-Cache-Hits": "0",
+          "X-Moose": "majestic",
+          "X-Served-By": "cache-ord1746-ORD",
+          "X-Timer": "S1482975512.140447,VS0,VE57",
+          "access-control-allow-origin": "*",
+          "access-control-expose-headers": "X-Reddit-Tracking, X-Moose",
+          "cache-control": "max-age=0, must-revalidate",
+          "x-content-type-options": "nosniff",
+          "x-frame-options": "SAMEORIGIN",
+          "x-reddit-tracking": "https://pixel.redditmedia.com/pixel/of_destiny.png?v=TcngVum1mDzY4ET5NBd8s1JBqT6O%2FZP44Dg1t9Vb2hmevB9Az87IILAojI56jDkOTBkloX8TJpBQsLFvmJOuSuZ%2B7beYBq07",
+          "x-ua-compatible": "IE=edge",
+          "x-xss-protection": "1; mode=block"
+        },
+        "status": {
+          "code": 200,
+          "message": "OK"
+        },
+        "url": "https://oauth.reddit.com/r/<TEST_SUBREDDIT>/about/rules?raw_json=1"
+      }
+    }
+  ],
+  "recorded_with": "betamax/0.8.0"
+}
\ No newline at end of file
diff --git a/tests/integration/models/reddit/test_subreddit.py b/tests/integration/models/reddit/test_subreddit.py
--- a/tests/integration/models/reddit/test_subreddit.py
+++ b/tests/integration/models/reddit/test_subreddit.py
@@ -76,6 +76,12 @@ def test_random(self):
                            subreddit.random(), subreddit.random()]
             assert len(submissions) == len(set(submissions))
 
+    def test_rules(self):
+        with self.recorder.use_cassette('TestSubreddit.test_rules'):
+            subreddit = self.reddit.subreddit(
+                pytest.placeholders.test_subreddit)
+            assert subreddit.rules()['rules'][0]['short_name'] == 'Sample rule'
+
     def test_sticky(self):
         subreddit = self.reddit.subreddit(pytest.placeholders.test_subreddit)
         with self.recorder.use_cassette('TestSubreddit.test_sticky'):