0.3.9
This commit is contained in:
parent
00164bd3b5
commit
c61ce0bcb7
17 changed files with 238 additions and 673 deletions
|
|
@ -1,5 +1,10 @@
|
|||
# Changelog
|
||||
|
||||
## 0.3.9
|
||||
|
||||
- Cursor based pagination
|
||||
- Updated django version
|
||||
|
||||
## 0.3.8
|
||||
|
||||
- Update light / dark theme
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "newsreader",
|
||||
"version": "0.1.0",
|
||||
"version": "0.3.9",
|
||||
"description": "Application for viewing RSS feeds",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
|
|
|||
148
poetry.lock
generated
148
poetry.lock
generated
|
|
@ -37,10 +37,10 @@ optional = false
|
|||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[package.extras]
|
||||
dev = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"]
|
||||
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"]
|
||||
docs = ["furo", "sphinx", "zope.interface"]
|
||||
tests = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"]
|
||||
tests_no_zope = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"]
|
||||
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"]
|
||||
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"]
|
||||
|
||||
[[package]]
|
||||
name = "autoflake"
|
||||
|
|
@ -61,15 +61,13 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
soupsieve = {version = ">1.2", markers = "python_version >= \"3.0\""}
|
||||
|
||||
[package.extras]
|
||||
html5lib = ["html5lib"]
|
||||
lxml = ["lxml"]
|
||||
|
||||
[package.dependencies]
|
||||
[package.dependencies.soupsieve]
|
||||
version = ">1.2"
|
||||
python = ">=3.0"
|
||||
|
||||
[[package]]
|
||||
name = "billiard"
|
||||
version = "3.6.3.0"
|
||||
|
|
@ -86,15 +84,15 @@ category = "dev"
|
|||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.extras]
|
||||
d = ["aiohttp (>=3.3.2)", "aiohttp-cors"]
|
||||
|
||||
[package.dependencies]
|
||||
appdirs = "*"
|
||||
attrs = ">=18.1.0"
|
||||
click = ">=6.5"
|
||||
toml = ">=0.9.4"
|
||||
|
||||
[package.extras]
|
||||
d = ["aiohttp (>=3.3.2)", "aiohttp-cors"]
|
||||
|
||||
[[package]]
|
||||
name = "bleach"
|
||||
version = "3.2.1"
|
||||
|
|
@ -116,14 +114,20 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[package.dependencies]
|
||||
billiard = ">=3.6.3.0,<4.0"
|
||||
kombu = ">=4.6.10,<4.7"
|
||||
pytz = ">0.0-dev"
|
||||
vine = "1.3.0"
|
||||
|
||||
[package.extras]
|
||||
arangodb = ["pyArango (>=1.3.2)"]
|
||||
auth = ["cryptography"]
|
||||
azureblockblob = ["azure-storage (0.36.0)", "azure-common (1.1.5)", "azure-storage-common (1.1.0)"]
|
||||
azureblockblob = ["azure-storage (==0.36.0)", "azure-common (==1.1.5)", "azure-storage-common (==1.1.0)"]
|
||||
brotli = ["brotli (>=1.0.0)", "brotlipy (>=0.7.0)"]
|
||||
cassandra = ["cassandra-driver (<3.21.0)"]
|
||||
consul = ["python-consul"]
|
||||
cosmosdbsql = ["pydocumentdb (2.3.2)"]
|
||||
cosmosdbsql = ["pydocumentdb (==2.3.2)"]
|
||||
couchbase = ["couchbase-cffi (<3.0.0)", "couchbase (<3.0.0)"]
|
||||
couchdb = ["pycouchdb"]
|
||||
django = ["Django (>=1.11)"]
|
||||
|
|
@ -134,7 +138,7 @@ gevent = ["gevent"]
|
|||
librabbitmq = ["librabbitmq (>=1.5.0)"]
|
||||
lzma = ["backports.lzma"]
|
||||
memcache = ["pylibmc"]
|
||||
mongodb = ["pymongo (>=3.3.0)"]
|
||||
mongodb = ["pymongo[srv] (>=3.3.0)"]
|
||||
msgpack = ["msgpack"]
|
||||
pymemcache = ["python-memcached"]
|
||||
pyro = ["pyro4"]
|
||||
|
|
@ -144,18 +148,12 @@ s3 = ["boto3 (>=1.9.125)"]
|
|||
slmq = ["softlayer-messaging (>=1.0.3)"]
|
||||
solar = ["ephem"]
|
||||
sqlalchemy = ["sqlalchemy"]
|
||||
sqs = ["boto3 (>=1.9.125)", "pycurl (7.43.0.5)"]
|
||||
sqs = ["boto3 (>=1.9.125)", "pycurl (==7.43.0.5)"]
|
||||
tblib = ["tblib (>=1.3.0)", "tblib (>=1.5.0)"]
|
||||
yaml = ["PyYAML (>=3.10)"]
|
||||
zookeeper = ["kazoo (>=1.3.1)"]
|
||||
zstd = ["zstandard"]
|
||||
|
||||
[package.dependencies]
|
||||
billiard = ">=3.6.3.0,<4.0"
|
||||
kombu = ">=4.6.10,<4.7"
|
||||
pytz = ">0.0-dev"
|
||||
vine = "1.3.0"
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2020.12.5"
|
||||
|
|
@ -218,21 +216,21 @@ toml = ["toml"]
|
|||
|
||||
[[package]]
|
||||
name = "django"
|
||||
version = "3.1.5"
|
||||
version = "3.1.6"
|
||||
description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.extras]
|
||||
argon2 = ["argon2-cffi (>=16.1.0)"]
|
||||
bcrypt = ["bcrypt"]
|
||||
|
||||
[package.dependencies]
|
||||
asgiref = ">=3.2.10,<4"
|
||||
pytz = "*"
|
||||
sqlparse = ">=0.2.2"
|
||||
|
||||
[package.extras]
|
||||
argon2 = ["argon2-cffi (>=16.1.0)"]
|
||||
bcrypt = ["bcrypt"]
|
||||
|
||||
[[package]]
|
||||
name = "django-axes"
|
||||
version = "5.12.0"
|
||||
|
|
@ -306,13 +304,13 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[package.extras]
|
||||
rest_framework = ["djangorestframework (>=3.0.0)"]
|
||||
|
||||
[package.dependencies]
|
||||
django = ">=2.2"
|
||||
pytz = "*"
|
||||
|
||||
[package.extras]
|
||||
rest_framework = ["djangorestframework (>=3.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "djangorestframework"
|
||||
version = "3.12.2"
|
||||
|
|
@ -332,9 +330,6 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.extras]
|
||||
validation = ["swagger-spec-validator (>=2.1.0)"]
|
||||
|
||||
[package.dependencies]
|
||||
coreapi = ">=2.3.3"
|
||||
coreschema = ">=0.0.4"
|
||||
|
|
@ -345,6 +340,9 @@ packaging = "*"
|
|||
"ruamel.yaml" = ">=0.15.34"
|
||||
uritemplate = ">=3.0.0"
|
||||
|
||||
[package.extras]
|
||||
validation = ["swagger-spec-validator (>=2.1.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "factory-boy"
|
||||
version = "2.12.0"
|
||||
|
|
@ -413,9 +411,6 @@ gevent = ["gevent (>=0.13)"]
|
|||
setproctitle = ["setproctitle"]
|
||||
tornado = ["tornado (>=0.2)"]
|
||||
|
||||
[package.dependencies]
|
||||
setuptools = ">=3.0"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "2.10"
|
||||
|
|
@ -431,18 +426,14 @@ description = "Read metadata from Python packages"
|
|||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
marker = "python_version < \"3.8\""
|
||||
|
||||
[package.dependencies]
|
||||
typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""}
|
||||
zipp = ">=0.5"
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
|
||||
testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"]
|
||||
|
||||
[package.dependencies]
|
||||
zipp = ">=0.5"
|
||||
|
||||
[package.dependencies.typing-extensions]
|
||||
version = ">=3.6.4"
|
||||
python = "<3.8"
|
||||
testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"]
|
||||
|
||||
[[package]]
|
||||
name = "inflection"
|
||||
|
|
@ -482,12 +473,12 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[package.extras]
|
||||
i18n = ["Babel (>=0.8)"]
|
||||
|
||||
[package.dependencies]
|
||||
MarkupSafe = ">=0.23"
|
||||
|
||||
[package.extras]
|
||||
i18n = ["Babel (>=0.8)"]
|
||||
|
||||
[[package]]
|
||||
name = "kombu"
|
||||
version = "4.6.11"
|
||||
|
|
@ -496,6 +487,10 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[package.dependencies]
|
||||
amqp = ">=2.6.0,<2.7"
|
||||
importlib-metadata = {version = ">=0.18", markers = "python_version < \"3.8\""}
|
||||
|
||||
[package.extras]
|
||||
azureservicebus = ["azure-servicebus (>=0.21.1)"]
|
||||
azurestoragequeues = ["azure-storage-queue"]
|
||||
|
|
@ -508,17 +503,10 @@ qpid = ["qpid-python (>=0.26)", "qpid-tools (>=0.26)"]
|
|||
redis = ["redis (>=3.3.11)"]
|
||||
slmq = ["softlayer-messaging (>=1.0.3)"]
|
||||
sqlalchemy = ["sqlalchemy"]
|
||||
sqs = ["boto3 (>=1.4.4)", "pycurl (7.43.0.2)"]
|
||||
sqs = ["boto3 (>=1.4.4)", "pycurl (==7.43.0.2)"]
|
||||
yaml = ["PyYAML (>=3.10)"]
|
||||
zookeeper = ["kazoo (>=1.3.1)"]
|
||||
|
||||
[package.dependencies]
|
||||
amqp = ">=2.6.0,<2.7"
|
||||
|
||||
[package.dependencies.importlib-metadata]
|
||||
version = ">=0.18"
|
||||
python = "<3.8"
|
||||
|
||||
[[package]]
|
||||
name = "lxml"
|
||||
version = "4.6.2"
|
||||
|
|
@ -597,13 +585,13 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
python-dateutil = "*"
|
||||
|
||||
[package.extras]
|
||||
cron-description = ["cron-descriptor"]
|
||||
cron-schedule = ["croniter"]
|
||||
|
||||
[package.dependencies]
|
||||
python-dateutil = "*"
|
||||
|
||||
[[package]]
|
||||
name = "python-dateutil"
|
||||
version = "2.8.1"
|
||||
|
|
@ -653,16 +641,16 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[package.extras]
|
||||
security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
|
||||
socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"]
|
||||
|
||||
[package.dependencies]
|
||||
certifi = ">=2017.4.17"
|
||||
chardet = ">=3.0.2,<5"
|
||||
idna = ">=2.5,<3"
|
||||
urllib3 = ">=1.21.1,<1.27"
|
||||
|
||||
[package.extras]
|
||||
security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
|
||||
|
||||
[[package]]
|
||||
name = "requests-oauthlib"
|
||||
version = "1.3.0"
|
||||
|
|
@ -671,13 +659,13 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[package.extras]
|
||||
rsa = ["oauthlib (>=3.0.0)"]
|
||||
|
||||
[package.dependencies]
|
||||
oauthlib = ">=3.0.0"
|
||||
requests = ">=2.0.0"
|
||||
|
||||
[package.extras]
|
||||
rsa = ["oauthlib[signedtoken] (>=3.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "ruamel.yaml"
|
||||
version = "0.16.12"
|
||||
|
|
@ -686,15 +674,13 @@ category = "main"
|
|||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
"ruamel.yaml.clib" = {version = ">=0.1.2", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.9\""}
|
||||
|
||||
[package.extras]
|
||||
docs = ["ryd"]
|
||||
jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"]
|
||||
|
||||
[package.dependencies]
|
||||
[package.dependencies."ruamel.yaml.clib"]
|
||||
version = ">=0.1.2"
|
||||
python = "<3.9"
|
||||
|
||||
[[package]]
|
||||
name = "ruamel.yaml.clib"
|
||||
version = "0.2.2"
|
||||
|
|
@ -702,7 +688,6 @@ description = "C version of reader, parser and emitter for ruamel.yaml derived f
|
|||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
marker = "platform_python_implementation == \"CPython\" and python_version < \"3.9\""
|
||||
|
||||
[[package]]
|
||||
name = "sentry-sdk"
|
||||
|
|
@ -712,6 +697,10 @@ category = "main"
|
|||
optional = true
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
certifi = "*"
|
||||
urllib3 = ">=1.10.0"
|
||||
|
||||
[package.extras]
|
||||
aiohttp = ["aiohttp (>=3.5)"]
|
||||
beam = ["beam (>=2.12)"]
|
||||
|
|
@ -726,10 +715,6 @@ sanic = ["sanic (>=0.8)"]
|
|||
sqlalchemy = ["sqlalchemy (>=1.2)"]
|
||||
tornado = ["tornado (>=5)"]
|
||||
|
||||
[package.dependencies]
|
||||
certifi = "*"
|
||||
urllib3 = ">=1.10.0"
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.15.0"
|
||||
|
|
@ -745,7 +730,6 @@ description = "A modern CSS selector implementation for Beautiful Soup."
|
|||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
marker = "python_version >= \"3.0\""
|
||||
|
||||
[[package]]
|
||||
name = "sqlparse"
|
||||
|
|
@ -786,7 +770,6 @@ description = "Backported and Experimental Type Hints for Python 3.5+"
|
|||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
marker = "python_version < \"3.8\""
|
||||
|
||||
[[package]]
|
||||
name = "uritemplate"
|
||||
|
|
@ -807,7 +790,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
|
|||
[package.extras]
|
||||
brotli = ["brotlipy (>=0.6.0)"]
|
||||
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
|
||||
socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"]
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "vine"
|
||||
|
|
@ -840,17 +823,16 @@ description = "Backport of pathlib-compatible object wrapper for zip files"
|
|||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
marker = "python_version < \"3.8\""
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
|
||||
testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]
|
||||
testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]
|
||||
|
||||
[extras]
|
||||
sentry = ["sentry-sdk"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "1.0"
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.7"
|
||||
content-hash = "051ae963128801a760a39a286257ec7d4faa8f1d8a47739fba80fdae6450002b"
|
||||
|
||||
|
|
@ -967,8 +949,8 @@ coverage = [
|
|||
{file = "coverage-5.3.1.tar.gz", hash = "sha256:38f16b1317b8dd82df67ed5daa5f5e7c959e46579840d77a67a4ceb9cef0a50b"},
|
||||
]
|
||||
django = [
|
||||
{file = "Django-3.1.5-py3-none-any.whl", hash = "sha256:efa2ab96b33b20c2182db93147a0c3cd7769d418926f9e9f140a60dca7c64ca9"},
|
||||
{file = "Django-3.1.5.tar.gz", hash = "sha256:2d78425ba74c7a1a74b196058b261b9733a8570782f4e2828974777ccca7edf7"},
|
||||
{file = "Django-3.1.6-py3-none-any.whl", hash = "sha256:169e2e7b4839a7910b393eec127fd7cbae62e80fa55f89c6510426abf673fe5f"},
|
||||
{file = "Django-3.1.6.tar.gz", hash = "sha256:c6c0462b8b361f8691171af1fb87eceb4442da28477e12200c40420176206ba7"},
|
||||
]
|
||||
django-axes = [
|
||||
{file = "django-axes-5.12.0.tar.gz", hash = "sha256:c26167f7ca2003df8358eb23537dffb1d97bd9f44ccef70d5c64a7aba2349456"},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "newsreader"
|
||||
version = "0.2"
|
||||
version = "0.3.9"
|
||||
description = "Webapplication for reading RSS feeds"
|
||||
authors = ["Sonny <sonnyba871@gmail.com>"]
|
||||
license = "GPL-3.0"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from rest_framework.pagination import PageNumberPagination
|
||||
from rest_framework import pagination
|
||||
|
||||
|
||||
class ResultSetPagination(PageNumberPagination):
|
||||
class ResultSetPagination(pagination.PageNumberPagination):
|
||||
page_size_query_param = "count"
|
||||
max_page_size = 50
|
||||
page_size = 30
|
||||
|
|
@ -10,3 +10,9 @@ class ResultSetPagination(PageNumberPagination):
|
|||
class LargeResultSetPagination(ResultSetPagination):
|
||||
max_page_size = 100
|
||||
page_size = 50
|
||||
|
||||
|
||||
class CursorPagination(pagination.CursorPagination):
|
||||
page_size_query_param = "count"
|
||||
ordering = "-publication_date"
|
||||
page_size = 30
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ export const markPostRead = (post, token) => {
|
|||
};
|
||||
};
|
||||
|
||||
export const fetchPostsBySection = (section, page = false) => {
|
||||
export const fetchPostsBySection = (section, next = false) => {
|
||||
return dispatch => {
|
||||
if (section.unread === 0) {
|
||||
return;
|
||||
|
|
@ -76,10 +76,10 @@ export const fetchPostsBySection = (section, page = false) => {
|
|||
|
||||
switch (section.type) {
|
||||
case RULE_TYPE:
|
||||
url = page ? page : `/api/rules/${section.id}/posts/?read=false`;
|
||||
url = next ? next : `/api/rules/${section.id}/posts/?read=false`;
|
||||
break;
|
||||
case CATEGORY_TYPE:
|
||||
url = page ? page : `/api/categories/${section.id}/posts/?read=false`;
|
||||
url = next ? next : `/api/categories/${section.id}/posts/?read=false`;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ const mapStateToProps = state => ({
|
|||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
fetchPostsBySection: (rule, page = false) => dispatch(fetchPostsBySection(rule, page)),
|
||||
fetchPostsBySection: (rule, next = false) => dispatch(fetchPostsBySection(rule, next)),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(PostList);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ if (page) {
|
|||
const settings = JSON.parse(document.getElementById('homepageSettings').textContent);
|
||||
const { feedUrl, subredditUrl, timelineUrl, categoriesUrl } = settings;
|
||||
|
||||
ReactDOM.render(
|
||||
const app = (
|
||||
<Provider store={store}>
|
||||
<App
|
||||
feedUrl={feedUrl.substring(1, feedUrl.length - 3)}
|
||||
|
|
@ -24,7 +24,8 @@ if (page) {
|
|||
timezone={settings.timezone}
|
||||
autoMarking={settings.autoMarking}
|
||||
/>
|
||||
</Provider>,
|
||||
page
|
||||
</Provider>
|
||||
);
|
||||
|
||||
ReactDOM.render(app, page);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,16 @@ from rest_framework import status
|
|||
from rest_framework.generics import (
|
||||
GenericAPIView,
|
||||
ListAPIView,
|
||||
RetrieveUpdateDestroyAPIView,
|
||||
RetrieveUpdateAPIView,
|
||||
get_object_or_404,
|
||||
)
|
||||
from rest_framework.response import Response
|
||||
|
||||
from newsreader.core.pagination import LargeResultSetPagination, ResultSetPagination
|
||||
from newsreader.core.pagination import (
|
||||
CursorPagination,
|
||||
LargeResultSetPagination,
|
||||
ResultSetPagination,
|
||||
)
|
||||
from newsreader.news.collection.models import CollectionRule
|
||||
from newsreader.news.collection.serializers import RuleSerializer
|
||||
from newsreader.news.core.filters import ReadFilter
|
||||
|
|
@ -15,26 +19,15 @@ from newsreader.news.core.models import Post
|
|||
from newsreader.news.core.serializers import PostSerializer
|
||||
|
||||
|
||||
class ListRuleView(ListAPIView):
|
||||
class DetailRuleView(RetrieveUpdateAPIView):
|
||||
queryset = CollectionRule.objects.all()
|
||||
serializer_class = RuleSerializer
|
||||
pagination_class = ResultSetPagination
|
||||
|
||||
def get_queryset(self):
|
||||
user = self.request.user
|
||||
return self.queryset.filter(user=user).order_by("-created")
|
||||
|
||||
|
||||
class DetailRuleView(RetrieveUpdateDestroyAPIView):
|
||||
queryset = CollectionRule.objects.all()
|
||||
serializer_class = RuleSerializer
|
||||
pagination_class = ResultSetPagination
|
||||
|
||||
|
||||
class NestedRuleView(ListAPIView):
|
||||
queryset = CollectionRule.objects.prefetch_related("posts").all()
|
||||
serializer_class = PostSerializer
|
||||
pagination_class = LargeResultSetPagination
|
||||
pagination_class = CursorPagination
|
||||
filter_backends = [ReadFilter]
|
||||
|
||||
def get_queryset(self):
|
||||
|
|
|
|||
|
|
@ -121,15 +121,6 @@ class CollectionRuleDetailViewTestCase(TestCase):
|
|||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["name"], "BBC")
|
||||
|
||||
def test_delete(self):
|
||||
rule = FeedFactory(user=self.user)
|
||||
|
||||
response = self.client.delete(
|
||||
reverse("api:news:collection:rules-detail", args=[rule.pk])
|
||||
)
|
||||
|
||||
self.assertEquals(response.status_code, 204)
|
||||
|
||||
def test_rule_with_unauthenticated_user(self):
|
||||
self.client.logout()
|
||||
|
||||
|
|
|
|||
|
|
@ -12,137 +12,6 @@ from newsreader.news.collection.tests.factories import FeedFactory
|
|||
from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory
|
||||
|
||||
|
||||
class RuleListViewTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.user = UserFactory(password="test")
|
||||
self.client.force_login(self.user)
|
||||
|
||||
def test_simple(self):
|
||||
FeedFactory.create_batch(size=3, user=self.user)
|
||||
|
||||
response = self.client.get(reverse("api:news:collection:rules-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertTrue("results" in data)
|
||||
self.assertTrue("count" in data)
|
||||
self.assertEquals(data["count"], 3)
|
||||
|
||||
def test_ordering(self):
|
||||
rules = [
|
||||
FeedFactory(
|
||||
created=datetime.combine(
|
||||
date(2019, 5, 20), time(hour=16, minute=7, second=37), pytz.utc
|
||||
),
|
||||
user=self.user,
|
||||
),
|
||||
FeedFactory(
|
||||
created=datetime.combine(
|
||||
date(2019, 7, 20), time(hour=18, minute=7, second=37), pytz.utc
|
||||
),
|
||||
user=self.user,
|
||||
),
|
||||
FeedFactory(
|
||||
created=datetime.combine(
|
||||
date(2019, 7, 20), time(hour=16, minute=7, second=37), pytz.utc
|
||||
),
|
||||
user=self.user,
|
||||
),
|
||||
]
|
||||
|
||||
response = self.client.get(reverse("api:news:collection:rules-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertTrue("results" in data)
|
||||
self.assertTrue("count" in data)
|
||||
self.assertEquals(data["count"], 3)
|
||||
|
||||
self.assertEquals(data["results"][0]["id"], rules[1].pk)
|
||||
self.assertEquals(data["results"][1]["id"], rules[2].pk)
|
||||
self.assertEquals(data["results"][2]["id"], rules[0].pk)
|
||||
|
||||
def test_pagination_count(self):
|
||||
FeedFactory.create_batch(size=80, user=self.user)
|
||||
|
||||
response = self.client.get(
|
||||
reverse("api:news:collection:rules-list"), {"count": 30}
|
||||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["count"], 80)
|
||||
self.assertEquals(len(data["results"]), 30)
|
||||
|
||||
def test_empty(self):
|
||||
response = self.client.get(reverse("api:news:collection:rules-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertTrue("results" in data)
|
||||
self.assertTrue("count" in data)
|
||||
|
||||
self.assertEquals(data["count"], 0)
|
||||
self.assertEquals(len(data["results"]), 0)
|
||||
|
||||
def test_post(self):
|
||||
category = CategoryFactory(user=self.user)
|
||||
|
||||
data = {"name": "BBC", "url": "https://www.bbc.co.uk", "category": category.pk}
|
||||
|
||||
response = self.client.post(
|
||||
reverse("api:news:collection:rules-list"),
|
||||
data=json.dumps(data),
|
||||
content_type="application/json",
|
||||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "POST" not allowed.')
|
||||
|
||||
def test_patch(self):
|
||||
response = self.client.patch(reverse("api:news:collection:rules-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "PATCH" not allowed.')
|
||||
|
||||
def test_put(self):
|
||||
response = self.client.put(reverse("api:news:collection:rules-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "PUT" not allowed.')
|
||||
|
||||
def test_delete(self):
|
||||
response = self.client.delete(reverse("api:news:collection:rules-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "DELETE" not allowed.')
|
||||
|
||||
def test_rules_with_unauthenticated_user(self):
|
||||
self.client.logout()
|
||||
|
||||
FeedFactory.create_batch(size=3, user=self.user)
|
||||
|
||||
response = self.client.get(reverse("api:news:collection:rules-list"))
|
||||
|
||||
self.assertEquals(response.status_code, 403)
|
||||
|
||||
def test_rules_with_unauthorized_user(self):
|
||||
other_user = UserFactory()
|
||||
FeedFactory.create_batch(size=3, user=other_user)
|
||||
|
||||
response = self.client.get(reverse("api:news:collection:rules-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
self.assertEquals(data["count"], 0)
|
||||
self.assertEquals(len(data["results"]), 0)
|
||||
|
||||
|
||||
class NestedRuleListViewTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.user = UserFactory(password="test")
|
||||
|
|
@ -157,11 +26,10 @@ class NestedRuleListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
self.assertTrue("results" in data)
|
||||
self.assertTrue("count" in data)
|
||||
self.assertEquals(data["count"], 5)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data["results"]), 5)
|
||||
self.assertEqual(data["next"], None)
|
||||
self.assertEqual(data["previous"], None)
|
||||
|
||||
def test_pagination(self):
|
||||
rule = FeedFactory.create(user=self.user)
|
||||
|
|
@ -178,11 +46,12 @@ class NestedRuleListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["count"], 80)
|
||||
self.assertEquals(len(data["results"]), 30)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTrue(data["next"])
|
||||
self.assertFalse(data["previous"])
|
||||
|
||||
self.assertEquals(
|
||||
self.assertEqual(len(data["results"]), 30)
|
||||
self.assertEqual(
|
||||
[post["id"] for post in data["results"]], [post.id for post in posts[:30]]
|
||||
)
|
||||
|
||||
|
|
@ -194,16 +63,15 @@ class NestedRuleListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["count"], 0)
|
||||
self.assertEquals(len(data["results"]), 0)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data["results"]), 0)
|
||||
|
||||
def test_not_known(self):
|
||||
response = self.client.get(
|
||||
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": 0})
|
||||
)
|
||||
|
||||
self.assertEquals(response.status_code, 404)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_post(self):
|
||||
rule = FeedFactory.create(user=self.user)
|
||||
|
|
@ -215,8 +83,8 @@ class NestedRuleListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "POST" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(data["detail"], 'Method "POST" not allowed.')
|
||||
|
||||
def test_patch(self):
|
||||
rule = FeedFactory.create(user=self.user)
|
||||
|
|
@ -228,8 +96,8 @@ class NestedRuleListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "PATCH" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(data["detail"], 'Method "PATCH" not allowed.')
|
||||
|
||||
def test_put(self):
|
||||
rule = FeedFactory.create(user=self.user)
|
||||
|
|
@ -241,8 +109,8 @@ class NestedRuleListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "PUT" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(data["detail"], 'Method "PUT" not allowed.')
|
||||
|
||||
def test_delete(self):
|
||||
rule = FeedFactory.create(user=self.user)
|
||||
|
|
@ -254,8 +122,8 @@ class NestedRuleListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "DELETE" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(data["detail"], 'Method "DELETE" not allowed.')
|
||||
|
||||
def test_rule_with_unauthenticated_user(self):
|
||||
self.client.logout()
|
||||
|
|
@ -266,7 +134,7 @@ class NestedRuleListViewTestCase(TestCase):
|
|||
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk})
|
||||
)
|
||||
|
||||
self.assertEquals(response.status_code, 403)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_rule_with_unauthorized_user(self):
|
||||
other_user = UserFactory()
|
||||
|
|
@ -276,7 +144,7 @@ class NestedRuleListViewTestCase(TestCase):
|
|||
reverse("api:news:collection:rules-nested-posts", kwargs={"pk": rule.pk})
|
||||
)
|
||||
|
||||
self.assertEquals(response.status_code, 403)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_posts_ordering(self):
|
||||
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||
|
|
@ -310,14 +178,12 @@ class NestedRuleListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertTrue("results" in data)
|
||||
self.assertTrue("count" in data)
|
||||
self.assertEquals(data["count"], 3)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data["results"]), 3)
|
||||
|
||||
self.assertEquals(data["results"][0]["id"], posts[1].pk)
|
||||
self.assertEquals(data["results"][1]["id"], posts[2].pk)
|
||||
self.assertEquals(data["results"][2]["id"], posts[0].pk)
|
||||
self.assertEqual(data["results"][0]["id"], posts[1].pk)
|
||||
self.assertEqual(data["results"][1]["id"], posts[2].pk)
|
||||
self.assertEqual(data["results"][2]["id"], posts[0].pk)
|
||||
|
||||
def test_only_posts_from_rule_are_returned(self):
|
||||
rule = FeedFactory.create(user=self.user)
|
||||
|
|
@ -331,14 +197,12 @@ class NestedRuleListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
self.assertTrue("results" in data)
|
||||
self.assertTrue("count" in data)
|
||||
self.assertEquals(data["count"], 5)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data["results"]), 5)
|
||||
|
||||
for post in data["results"]:
|
||||
self.assertEquals(post["rule"], rule.pk)
|
||||
with self.subTest(post=post):
|
||||
self.assertEqual(post["rule"], rule.pk)
|
||||
|
||||
def test_unread_posts(self):
|
||||
rule = FeedFactory.create(user=self.user)
|
||||
|
|
@ -352,13 +216,13 @@ class NestedRuleListViewTestCase(TestCase):
|
|||
)
|
||||
|
||||
data = response.json()
|
||||
posts = data["results"]
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["count"], 10)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data["results"]), 10)
|
||||
|
||||
for post in posts:
|
||||
self.assertEquals(post["read"], False)
|
||||
for post in data["results"]:
|
||||
with self.subTest(post=post):
|
||||
self.assertEqual(post["read"], False)
|
||||
|
||||
def test_read_posts(self):
|
||||
rule = FeedFactory.create(user=self.user)
|
||||
|
|
@ -372,10 +236,10 @@ class NestedRuleListViewTestCase(TestCase):
|
|||
)
|
||||
|
||||
data = response.json()
|
||||
posts = data["results"]
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["count"], 10)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data["results"]), 10)
|
||||
|
||||
for post in posts:
|
||||
self.assertEquals(post["read"], True)
|
||||
for post in data["results"]:
|
||||
with self.subTest(post=post):
|
||||
self.assertEqual(post["read"], True)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ from django.urls import path
|
|||
|
||||
from newsreader.news.collection.endpoints import (
|
||||
DetailRuleView,
|
||||
ListRuleView,
|
||||
NestedRuleView,
|
||||
RuleReadView,
|
||||
)
|
||||
|
|
@ -26,7 +25,6 @@ endpoints = [
|
|||
path("rules/<int:pk>/", DetailRuleView.as_view(), name="rules-detail"),
|
||||
path("rules/<int:pk>/posts/", NestedRuleView.as_view(), name="rules-nested-posts"),
|
||||
path("rules/<int:pk>/read/", RuleReadView.as_view(), name="rules-read"),
|
||||
path("rules/", ListRuleView.as_view(), name="rules-list"),
|
||||
]
|
||||
|
||||
urlpatterns = [
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from django.db.models import Q
|
||||
|
||||
from rest_framework import status
|
||||
from rest_framework.generics import (
|
||||
GenericAPIView,
|
||||
|
|
@ -13,30 +11,13 @@ from rest_framework.permissions import IsAuthenticated
|
|||
from rest_framework.response import Response
|
||||
|
||||
from newsreader.accounts.permissions import IsPostOwner
|
||||
from newsreader.core.pagination import LargeResultSetPagination
|
||||
from newsreader.core.pagination import CursorPagination
|
||||
from newsreader.news.collection.serializers import RuleSerializer
|
||||
from newsreader.news.core.filters import ReadFilter
|
||||
from newsreader.news.core.models import Category, Post
|
||||
from newsreader.news.core.serializers import CategorySerializer, PostSerializer
|
||||
|
||||
|
||||
class ListPostView(ListAPIView):
|
||||
queryset = Post.objects.all()
|
||||
serializer_class = PostSerializer
|
||||
pagination_class = LargeResultSetPagination
|
||||
filter_backends = [ReadFilter]
|
||||
|
||||
def get_queryset(self):
|
||||
user = self.request.user
|
||||
queryset = (
|
||||
self.queryset.filter(rule__user=user)
|
||||
.filter(Q(rule__category=None) | Q(rule__category__user=user))
|
||||
.order_by("rule", "-publication_date", "-created")
|
||||
)
|
||||
|
||||
return queryset
|
||||
|
||||
|
||||
class DetailPostView(RetrieveUpdateAPIView):
|
||||
queryset = Post.objects.all()
|
||||
serializer_class = PostSerializer
|
||||
|
|
@ -77,7 +58,7 @@ class NestedRuleCategoryView(ListAPIView):
|
|||
class NestedPostCategoryView(ListAPIView):
|
||||
queryset = Category.objects.prefetch_related("rules", "rules__posts").all()
|
||||
serializer_class = PostSerializer
|
||||
pagination_class = LargeResultSetPagination
|
||||
pagination_class = CursorPagination
|
||||
filter_backends = [ReadFilter]
|
||||
|
||||
def get_queryset(self):
|
||||
|
|
@ -90,9 +71,8 @@ class NestedPostCategoryView(ListAPIView):
|
|||
category = get_object_or_404(self.queryset, **filter_kwargs)
|
||||
self.check_object_permissions(self.request, category)
|
||||
|
||||
queryset = Post.objects.filter(
|
||||
rule__in=category.rules.values_list("id", flat=True)
|
||||
).order_by("-publication_date", "rule__name")
|
||||
rules = category.rules.values_list("id", flat=True)
|
||||
queryset = Post.objects.filter(rule__in=rules)
|
||||
|
||||
return queryset
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import json
|
||||
|
||||
from datetime import date, datetime, time
|
||||
from datetime import datetime
|
||||
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
|
|
@ -23,27 +23,21 @@ class CategoryListViewTestCase(TestCase):
|
|||
response = self.client.get(reverse("api:news:core:categories-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(len(data), 3)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data), 3)
|
||||
|
||||
def test_ordering(self):
|
||||
categories = [
|
||||
CategoryFactory(
|
||||
created=datetime.combine(
|
||||
date(2019, 5, 20), time(hour=16, minute=7, second=37), pytz.utc
|
||||
),
|
||||
created=datetime(2019, 5, 20, 16, 7, 37, tzinfo=pytz.utc),
|
||||
user=self.user,
|
||||
),
|
||||
CategoryFactory(
|
||||
created=datetime.combine(
|
||||
date(2019, 7, 20), time(hour=18, minute=7, second=37), pytz.utc
|
||||
),
|
||||
created=datetime(2019, 7, 20, 18, 7, 37, tzinfo=pytz.utc),
|
||||
user=self.user,
|
||||
),
|
||||
CategoryFactory(
|
||||
created=datetime.combine(
|
||||
date(2019, 7, 20), time(hour=16, minute=7, second=37), pytz.utc
|
||||
),
|
||||
created=datetime(2019, 7, 20, 16, 7, 37, tzinfo=pytz.utc),
|
||||
user=self.user,
|
||||
),
|
||||
]
|
||||
|
|
@ -51,18 +45,18 @@ class CategoryListViewTestCase(TestCase):
|
|||
response = self.client.get(reverse("api:news:core:categories-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.assertEquals(data[0]["id"], categories[1].pk)
|
||||
self.assertEquals(data[1]["id"], categories[2].pk)
|
||||
self.assertEquals(data[2]["id"], categories[0].pk)
|
||||
self.assertEqual(data[0]["id"], categories[1].pk)
|
||||
self.assertEqual(data[1]["id"], categories[2].pk)
|
||||
self.assertEqual(data[2]["id"], categories[0].pk)
|
||||
|
||||
def test_empty(self):
|
||||
response = self.client.get(reverse("api:news:core:categories-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(len(data), 0)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data), 0)
|
||||
|
||||
def test_post(self):
|
||||
data = {"name": "Tech"}
|
||||
|
|
@ -74,29 +68,29 @@ class CategoryListViewTestCase(TestCase):
|
|||
)
|
||||
response_data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(response_data["detail"], 'Method "POST" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(response_data["detail"], 'Method "POST" not allowed.')
|
||||
|
||||
def test_patch(self):
|
||||
response = self.client.patch(reverse("api:news:core:categories-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "PATCH" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(data["detail"], 'Method "PATCH" not allowed.')
|
||||
|
||||
def test_put(self):
|
||||
response = self.client.put(reverse("api:news:core:categories-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "PUT" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(data["detail"], 'Method "PUT" not allowed.')
|
||||
|
||||
def test_delete(self):
|
||||
response = self.client.delete(reverse("api:news:core:categories-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "DELETE" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(data["detail"], 'Method "DELETE" not allowed.')
|
||||
|
||||
def test_categories_with_unauthenticated_user(self):
|
||||
self.client.logout()
|
||||
|
|
@ -105,7 +99,7 @@ class CategoryListViewTestCase(TestCase):
|
|||
|
||||
response = self.client.get(reverse("api:news:core:categories-list"))
|
||||
|
||||
self.assertEquals(response.status_code, 403)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_categories_with_unauthorized_user(self):
|
||||
other_user = UserFactory()
|
||||
|
|
@ -114,8 +108,8 @@ class CategoryListViewTestCase(TestCase):
|
|||
response = self.client.get(reverse("api:news:core:categories-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(len(data), 0)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data), 0)
|
||||
|
||||
|
||||
class NestedCategoryListViewTestCase(TestCase):
|
||||
|
|
@ -132,8 +126,8 @@ class NestedCategoryListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(len(data), 5)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data), 5)
|
||||
|
||||
self.assertTrue("id" in data[0])
|
||||
self.assertTrue("name" in data[0])
|
||||
|
|
@ -149,16 +143,16 @@ class NestedCategoryListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(len(data), 0)
|
||||
self.assertEquals(data, [])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data), 0)
|
||||
self.assertEqual(data, [])
|
||||
|
||||
def test_not_known(self):
|
||||
response = self.client.get(
|
||||
reverse("api:news:core:categories-nested-rules", kwargs={"pk": 100})
|
||||
)
|
||||
|
||||
self.assertEquals(response.status_code, 404)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_post(self):
|
||||
response = self.client.post(
|
||||
|
|
@ -168,8 +162,8 @@ class NestedCategoryListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "POST" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(data["detail"], 'Method "POST" not allowed.')
|
||||
|
||||
def test_patch(self):
|
||||
category = CategoryFactory.create(user=self.user)
|
||||
|
|
@ -183,8 +177,8 @@ class NestedCategoryListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "PATCH" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(data["detail"], 'Method "PATCH" not allowed.')
|
||||
|
||||
def test_put(self):
|
||||
category = CategoryFactory.create(user=self.user)
|
||||
|
|
@ -198,8 +192,8 @@ class NestedCategoryListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "PUT" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(data["detail"], 'Method "PUT" not allowed.')
|
||||
|
||||
def test_delete(self):
|
||||
category = CategoryFactory.create(user=self.user)
|
||||
|
|
@ -212,8 +206,8 @@ class NestedCategoryListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "DELETE" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(data["detail"], 'Method "DELETE" not allowed.')
|
||||
|
||||
def test_with_unauthenticated_user(self):
|
||||
self.client.logout()
|
||||
|
|
@ -225,7 +219,7 @@ class NestedCategoryListViewTestCase(TestCase):
|
|||
reverse("api:news:core:categories-nested-rules", kwargs={"pk": category.pk})
|
||||
)
|
||||
|
||||
self.assertEquals(response.status_code, 403)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_with_unauthorized_user(self):
|
||||
other_user = UserFactory.create()
|
||||
|
|
@ -237,7 +231,7 @@ class NestedCategoryListViewTestCase(TestCase):
|
|||
reverse("api:news:core:categories-nested-rules", kwargs={"pk": category.pk})
|
||||
)
|
||||
|
||||
self.assertEquals(response.status_code, 403)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_ordering(self):
|
||||
category = CategoryFactory.create(user=self.user)
|
||||
|
|
@ -252,12 +246,12 @@ class NestedCategoryListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(len(data), 3)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data), 3)
|
||||
|
||||
self.assertEquals(data[0]["id"], rules[2].pk)
|
||||
self.assertEquals(data[1]["id"], rules[0].pk)
|
||||
self.assertEquals(data[2]["id"], rules[1].pk)
|
||||
self.assertEqual(data[0]["id"], rules[2].pk)
|
||||
self.assertEqual(data[1]["id"], rules[0].pk)
|
||||
self.assertEqual(data[2]["id"], rules[1].pk)
|
||||
|
||||
def test_only_rules_from_category_are_returned(self):
|
||||
other_category = CategoryFactory(user=self.user)
|
||||
|
|
@ -275,12 +269,12 @@ class NestedCategoryListViewTestCase(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(len(data), 3)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data), 3)
|
||||
|
||||
self.assertEquals(data[0]["id"], rules[2].pk)
|
||||
self.assertEquals(data[1]["id"], rules[0].pk)
|
||||
self.assertEquals(data[2]["id"], rules[1].pk)
|
||||
self.assertEqual(data[0]["id"], rules[2].pk)
|
||||
self.assertEqual(data[1]["id"], rules[0].pk)
|
||||
self.assertEqual(data[2]["id"], rules[1].pk)
|
||||
|
||||
|
||||
class NestedCategoryPostView(TestCase):
|
||||
|
|
@ -301,16 +295,15 @@ class NestedCategoryPostView(TestCase):
|
|||
reverse("api:news:core:categories-nested-posts", kwargs={"pk": category.pk})
|
||||
)
|
||||
data = response.json()
|
||||
posts = data["results"]
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["count"], 25)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data["results"]), 25)
|
||||
|
||||
self.assertTrue("id" in posts[0])
|
||||
self.assertTrue("title" in posts[0])
|
||||
self.assertTrue("body" in posts[0])
|
||||
self.assertTrue("rule" in posts[0])
|
||||
self.assertTrue("url" in posts[0])
|
||||
self.assertTrue("id" in data["results"][0])
|
||||
self.assertTrue("title" in data["results"][0])
|
||||
self.assertTrue("body" in data["results"][0])
|
||||
self.assertTrue("rule" in data["results"][0])
|
||||
self.assertTrue("url" in data["results"][0])
|
||||
|
||||
def test_no_rules(self):
|
||||
category = CategoryFactory.create(user=self.user)
|
||||
|
|
@ -321,9 +314,9 @@ class NestedCategoryPostView(TestCase):
|
|||
data = response.json()
|
||||
posts = data["results"]
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["count"], 0)
|
||||
self.assertEquals(posts, [])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data["results"]), 0)
|
||||
self.assertEqual(posts, [])
|
||||
|
||||
def test_no_posts(self):
|
||||
category = CategoryFactory.create(user=self.user)
|
||||
|
|
@ -335,16 +328,16 @@ class NestedCategoryPostView(TestCase):
|
|||
data = response.json()
|
||||
posts = data["results"]
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["count"], 0)
|
||||
self.assertEquals(posts, [])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data["results"]), 0)
|
||||
self.assertEqual(posts, [])
|
||||
|
||||
def test_not_known(self):
|
||||
response = self.client.get(
|
||||
reverse("api:news:core:categories-nested-posts", kwargs={"pk": 100})
|
||||
)
|
||||
|
||||
self.assertEquals(response.status_code, 404)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_post(self):
|
||||
response = self.client.post(
|
||||
|
|
@ -354,8 +347,8 @@ class NestedCategoryPostView(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "POST" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(data["detail"], 'Method "POST" not allowed.')
|
||||
|
||||
def test_patch(self):
|
||||
category = CategoryFactory.create(user=self.user)
|
||||
|
|
@ -369,8 +362,8 @@ class NestedCategoryPostView(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "PATCH" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(data["detail"], 'Method "PATCH" not allowed.')
|
||||
|
||||
def test_put(self):
|
||||
category = CategoryFactory.create(user=self.user)
|
||||
|
|
@ -384,8 +377,8 @@ class NestedCategoryPostView(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "PUT" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(data["detail"], 'Method "PUT" not allowed.')
|
||||
|
||||
def test_delete(self):
|
||||
category = CategoryFactory.create(user=self.user)
|
||||
|
|
@ -398,8 +391,8 @@ class NestedCategoryPostView(TestCase):
|
|||
)
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "DELETE" not allowed.')
|
||||
self.assertEqual(response.status_code, 405)
|
||||
self.assertEqual(data["detail"], 'Method "DELETE" not allowed.')
|
||||
|
||||
def test_with_unauthenticated_user(self):
|
||||
self.client.logout()
|
||||
|
|
@ -410,7 +403,7 @@ class NestedCategoryPostView(TestCase):
|
|||
reverse("api:news:core:categories-nested-posts", kwargs={"pk": category.pk})
|
||||
)
|
||||
|
||||
self.assertEquals(response.status_code, 403)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_with_unauthorized_user(self):
|
||||
other_user = UserFactory.create()
|
||||
|
|
@ -420,7 +413,7 @@ class NestedCategoryPostView(TestCase):
|
|||
reverse("api:news:core:categories-nested-posts", kwargs={"pk": category.pk})
|
||||
)
|
||||
|
||||
self.assertEquals(response.status_code, 403)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_ordering(self):
|
||||
category = CategoryFactory.create(user=self.user)
|
||||
|
|
@ -437,16 +430,12 @@ class NestedCategoryPostView(TestCase):
|
|||
FeedPostFactory.create(
|
||||
title="Second Reuters post",
|
||||
rule=reuters_rule,
|
||||
publication_date=datetime.combine(
|
||||
date(2019, 5, 21), time(hour=16, minute=7, second=37), pytz.utc
|
||||
),
|
||||
publication_date=datetime(2019, 5, 21, 15, tzinfo=pytz.utc),
|
||||
),
|
||||
FeedPostFactory.create(
|
||||
title="First Reuters post",
|
||||
rule=reuters_rule,
|
||||
publication_date=datetime.combine(
|
||||
date(2019, 5, 20), time(hour=16, minute=7, second=37), pytz.utc
|
||||
),
|
||||
publication_date=datetime(2019, 5, 20, 12, tzinfo=pytz.utc),
|
||||
),
|
||||
]
|
||||
|
||||
|
|
@ -454,16 +443,12 @@ class NestedCategoryPostView(TestCase):
|
|||
FeedPostFactory.create(
|
||||
title="Second Guardian post",
|
||||
rule=guardian_rule,
|
||||
publication_date=datetime.combine(
|
||||
date(2019, 5, 21), time(hour=16, minute=7, second=37), pytz.utc
|
||||
),
|
||||
publication_date=datetime(2019, 5, 21, 14, tzinfo=pytz.utc),
|
||||
),
|
||||
FeedPostFactory.create(
|
||||
title="First Guardian post",
|
||||
rule=guardian_rule,
|
||||
publication_date=datetime.combine(
|
||||
date(2019, 5, 20), time(hour=16, minute=7, second=37), pytz.utc
|
||||
),
|
||||
publication_date=datetime(2019, 5, 20, 11, tzinfo=pytz.utc),
|
||||
),
|
||||
]
|
||||
|
||||
|
|
@ -471,16 +456,12 @@ class NestedCategoryPostView(TestCase):
|
|||
FeedPostFactory.create(
|
||||
title="Second BBC post",
|
||||
rule=bbc_rule,
|
||||
publication_date=datetime.combine(
|
||||
date(2019, 5, 21), time(hour=16, minute=7, second=37), pytz.utc
|
||||
),
|
||||
publication_date=datetime(2019, 5, 21, 16, tzinfo=pytz.utc),
|
||||
),
|
||||
FeedPostFactory.create(
|
||||
title="First BBC post",
|
||||
rule=bbc_rule,
|
||||
publication_date=datetime.combine(
|
||||
date(2019, 5, 20), time(hour=16, minute=7, second=37), pytz.utc
|
||||
),
|
||||
publication_date=datetime(2019, 5, 20, 13, tzinfo=pytz.utc),
|
||||
),
|
||||
]
|
||||
|
||||
|
|
@ -490,16 +471,16 @@ class NestedCategoryPostView(TestCase):
|
|||
data = response.json()
|
||||
posts = data["results"]
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["count"], 6)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data["results"]), 6)
|
||||
|
||||
self.assertEquals(posts[0]["title"], "Second BBC post")
|
||||
self.assertEquals(posts[1]["title"], "Second Reuters post")
|
||||
self.assertEquals(posts[2]["title"], "Second Guardian post")
|
||||
self.assertEqual(posts[0]["title"], "Second BBC post")
|
||||
self.assertEqual(posts[1]["title"], "Second Reuters post")
|
||||
self.assertEqual(posts[2]["title"], "Second Guardian post")
|
||||
|
||||
self.assertEquals(posts[3]["title"], "First BBC post")
|
||||
self.assertEquals(posts[4]["title"], "First Reuters post")
|
||||
self.assertEquals(posts[5]["title"], "First Guardian post")
|
||||
self.assertEqual(posts[3]["title"], "First BBC post")
|
||||
self.assertEqual(posts[4]["title"], "First Reuters post")
|
||||
self.assertEqual(posts[5]["title"], "First Guardian post")
|
||||
|
||||
def test_only_posts_from_category_are_returned(self):
|
||||
category = CategoryFactory.create(user=self.user)
|
||||
|
|
@ -526,11 +507,11 @@ class NestedCategoryPostView(TestCase):
|
|||
data = response.json()
|
||||
posts = data["results"]
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["count"], 2)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data["results"]), 2)
|
||||
|
||||
self.assertEquals(posts[0]["rule"], guardian_rule.pk)
|
||||
self.assertEquals(posts[1]["rule"], guardian_rule.pk)
|
||||
self.assertEqual(posts[0]["rule"], guardian_rule.pk)
|
||||
self.assertEqual(posts[1]["rule"], guardian_rule.pk)
|
||||
|
||||
def test_unread_posts(self):
|
||||
category = CategoryFactory.create(user=self.user)
|
||||
|
|
@ -549,11 +530,11 @@ class NestedCategoryPostView(TestCase):
|
|||
data = response.json()
|
||||
posts = data["results"]
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["count"], 10)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data["results"]), 10)
|
||||
|
||||
for post in posts:
|
||||
self.assertEquals(post["read"], False)
|
||||
self.assertEqual(post["read"], False)
|
||||
|
||||
def test_read_posts(self):
|
||||
category = CategoryFactory.create(user=self.user)
|
||||
|
|
@ -572,8 +553,8 @@ class NestedCategoryPostView(TestCase):
|
|||
data = response.json()
|
||||
posts = data["results"]
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["count"], 10)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(data["results"]), 10)
|
||||
|
||||
for post in posts:
|
||||
self.assertEquals(post["read"], True)
|
||||
self.assertEqual(post["read"], True)
|
||||
|
|
|
|||
|
|
@ -1,234 +0,0 @@
|
|||
from datetime import date, datetime, time
|
||||
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
import pytz
|
||||
|
||||
from newsreader.accounts.tests.factories import UserFactory
|
||||
from newsreader.news.collection.tests.factories import FeedFactory
|
||||
from newsreader.news.core.tests.factories import CategoryFactory, FeedPostFactory
|
||||
|
||||
|
||||
class PostListViewTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.user = UserFactory(is_staff=True, password="test")
|
||||
self.client.force_login(self.user)
|
||||
|
||||
def test_simple(self):
|
||||
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||
FeedPostFactory.create_batch(size=3, rule=rule)
|
||||
|
||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertTrue("results" in data)
|
||||
self.assertTrue("count" in data)
|
||||
self.assertEquals(data["count"], 3)
|
||||
|
||||
def test_ordering(self):
|
||||
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||
|
||||
posts = [
|
||||
FeedPostFactory(
|
||||
title="I'm the first post",
|
||||
rule=rule,
|
||||
publication_date=datetime.combine(
|
||||
date(2019, 5, 20), time(hour=16, minute=7, second=37), pytz.utc
|
||||
),
|
||||
),
|
||||
FeedPostFactory(
|
||||
title="I'm the second post",
|
||||
rule=rule,
|
||||
publication_date=datetime.combine(
|
||||
date(2019, 7, 20), time(hour=18, minute=7, second=37), pytz.utc
|
||||
),
|
||||
),
|
||||
FeedPostFactory(
|
||||
title="I'm the third post",
|
||||
rule=rule,
|
||||
publication_date=datetime.combine(
|
||||
date(2019, 7, 20), time(hour=16, minute=7, second=37), pytz.utc
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertTrue("results" in data)
|
||||
self.assertTrue("count" in data)
|
||||
self.assertEquals(data["count"], 3)
|
||||
|
||||
self.assertEquals(data["results"][0]["id"], posts[1].pk)
|
||||
self.assertEquals(data["results"][1]["id"], posts[2].pk)
|
||||
self.assertEquals(data["results"][2]["id"], posts[0].pk)
|
||||
|
||||
def test_pagination_count(self):
|
||||
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||
FeedPostFactory.create_batch(size=80, rule=rule)
|
||||
page_size = 50
|
||||
|
||||
response = self.client.get(reverse("api:news:core:posts-list"), {"count": 50})
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["count"], 80)
|
||||
self.assertEquals(len(data["results"]), page_size)
|
||||
|
||||
def test_empty(self):
|
||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertTrue("results" in data)
|
||||
self.assertTrue("count" in data)
|
||||
|
||||
self.assertEquals(data["count"], 0)
|
||||
self.assertEquals(len(data["results"]), 0)
|
||||
|
||||
def test_post(self):
|
||||
response = self.client.post(reverse("api:news:core:posts-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "POST" not allowed.')
|
||||
|
||||
def test_patch(self):
|
||||
response = self.client.patch(reverse("api:news:core:posts-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "PATCH" not allowed.')
|
||||
|
||||
def test_put(self):
|
||||
response = self.client.put(reverse("api:news:core:posts-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "PUT" not allowed.')
|
||||
|
||||
def test_delete(self):
|
||||
response = self.client.delete(reverse("api:news:core:posts-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 405)
|
||||
self.assertEquals(data["detail"], 'Method "DELETE" not allowed.')
|
||||
|
||||
def test_posts_with_unauthenticated_user_without_category(self):
|
||||
self.client.logout()
|
||||
|
||||
FeedPostFactory.create_batch(size=3, rule=FeedFactory(user=self.user))
|
||||
|
||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||
|
||||
self.assertEquals(response.status_code, 403)
|
||||
|
||||
def test_posts_with_unauthenticated_user_with_category(self):
|
||||
self.client.logout()
|
||||
|
||||
category = CategoryFactory(user=self.user)
|
||||
|
||||
FeedPostFactory.create_batch(
|
||||
size=3, rule=FeedFactory(user=self.user, category=category)
|
||||
)
|
||||
|
||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||
|
||||
self.assertEquals(response.status_code, 403)
|
||||
|
||||
def test_posts_with_unauthorized_user_without_category(self):
|
||||
other_user = UserFactory()
|
||||
|
||||
rule = FeedFactory(user=other_user, category=None)
|
||||
FeedPostFactory.create_batch(size=3, rule=rule)
|
||||
|
||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(len(data["results"]), 0)
|
||||
self.assertEquals(data["count"], 0)
|
||||
|
||||
def test_posts_with_unauthorized_user_with_category(self):
|
||||
other_user = UserFactory()
|
||||
category = CategoryFactory(user=other_user)
|
||||
|
||||
FeedPostFactory.create_batch(
|
||||
size=3, rule=FeedFactory(user=other_user, category=category)
|
||||
)
|
||||
|
||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(len(data["results"]), 0)
|
||||
self.assertEquals(data["count"], 0)
|
||||
|
||||
# Note that this situation should not be possible, due to the user not being able
|
||||
# to specify the user when creating categories/rules
|
||||
def test_posts_with_authorized_rule_unauthorized_category(self):
|
||||
other_user = UserFactory()
|
||||
|
||||
rule = FeedFactory(user=self.user, category=CategoryFactory(user=other_user))
|
||||
FeedPostFactory.create_batch(size=3, rule=rule)
|
||||
|
||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertTrue("results" in data)
|
||||
self.assertTrue("count" in data)
|
||||
self.assertEquals(data["count"], 0)
|
||||
|
||||
def test_posts_with_authorized_user_without_category(self):
|
||||
rule = FeedFactory(user=self.user, category=None)
|
||||
FeedPostFactory.create_batch(size=3, rule=rule)
|
||||
|
||||
response = self.client.get(reverse("api:news:core:posts-list"))
|
||||
data = response.json()
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertTrue("results" in data)
|
||||
self.assertTrue("count" in data)
|
||||
self.assertEquals(data["count"], 3)
|
||||
|
||||
def test_unread_posts(self):
|
||||
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||
|
||||
FeedPostFactory.create_batch(size=10, rule=rule, read=False)
|
||||
FeedPostFactory.create_batch(size=10, rule=rule, read=True)
|
||||
|
||||
response = self.client.get(
|
||||
reverse("api:news:core:posts-list"), {"read": "false"}
|
||||
)
|
||||
|
||||
data = response.json()
|
||||
posts = data["results"]
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["count"], 10)
|
||||
|
||||
for post in posts:
|
||||
self.assertEquals(post["read"], False)
|
||||
|
||||
def test_read_posts(self):
|
||||
rule = FeedFactory(user=self.user, category=CategoryFactory(user=self.user))
|
||||
|
||||
FeedPostFactory.create_batch(size=20, rule=rule, read=False)
|
||||
FeedPostFactory.create_batch(size=10, rule=rule, read=True)
|
||||
|
||||
response = self.client.get(
|
||||
reverse("api:news:core:posts-list"), {"read": "true"}
|
||||
)
|
||||
|
||||
data = response.json()
|
||||
posts = data["results"]
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertEquals(data["count"], 10)
|
||||
|
||||
for post in posts:
|
||||
self.assertEquals(post["read"], True)
|
||||
|
|
@ -6,7 +6,6 @@ from newsreader.news.core.endpoints import (
|
|||
DetailCategoryView,
|
||||
DetailPostView,
|
||||
ListCategoryView,
|
||||
ListPostView,
|
||||
NestedPostCategoryView,
|
||||
NestedRuleCategoryView,
|
||||
)
|
||||
|
|
@ -33,7 +32,6 @@ urlpatterns = [
|
|||
]
|
||||
|
||||
endpoints = [
|
||||
path("posts/", ListPostView.as_view(), name="posts-list"),
|
||||
path("posts/<int:pk>/", DetailPostView.as_view(), name="posts-detail"),
|
||||
path("categories/", ListCategoryView.as_view(), name="categories-list"),
|
||||
path(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue