Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
9e2a8aa
Create Sponsor model
berinhard May 11, 2021
8e6fab6
Service column can be empty
berinhard May 11, 2021
3b49e92
Command to load sponsors to database
berinhard May 11, 2021
e2d039c
initdb should load sponsors
berinhard May 11, 2021
02d450a
Add sqlalchemy-utils as a dependency
berinhard May 12, 2021
5b5f150
Use URL type as fields and refactor to have a single migration
berinhard May 12, 2021
36ffefd
Populate images URL using current pypi static as the URL prefix
berinhard May 12, 2021
b6bf1de
Fix code lint warnings
berinhard May 12, 2021
918203a
Add direnv's .envrc to gitignore
berinhard May 14, 2021
c5f0d7a
Change sponsors page to read data from db instead of HTML include
berinhard May 14, 2021
582581f
Fix routes test
berinhard May 14, 2021
8d5b1cc
Unit test sponsors page
berinhard May 14, 2021
5f838e4
Better name for url field
berinhard May 18, 2021
023472f
Replace pickle by pg's array type
berinhard May 18, 2021
f8247e8
Update migration file
berinhard May 18, 2021
6d351c3
Revert "Unit test sponsors page"
berinhard May 18, 2021
c761787
Revert "Fix routes test"
berinhard May 18, 2021
4b92c8f
Revert "Change sponsors page to read data from db instead of HTML inc…
berinhard May 18, 2021
77b8d47
Test utils for sponsors app
berinhard May 18, 2021
9f9aec0
Add sponsors list to all requests (except for static files)
berinhard May 18, 2021
a70dc28
Update templates to read sponsors from request variable
berinhard May 18, 2021
0581a0f
Reformat
berinhard May 18, 2021
28dee11
Camoify logos
berinhard May 18, 2021
f9236e8
Merge branch 'main' into feature/sponsors-db
berinhard May 18, 2021
7c5021d
Add minimal sponsor list to admin
berinhard May 20, 2021
1707067
Add link to sponsors list
berinhard May 20, 2021
6983c69
Add minimal edit page
berinhard May 24, 2021
a69bf77
Merge branch 'main' into feature/sponsors-db
berinhard May 24, 2021
a0a88f1
Reformat
berinhard May 24, 2021
741e90a
Simple admin view to create sponsors
berinhard May 26, 2021
f370a72
Unit test sponsors admin
berinhard May 26, 2021
e21fb9b
Update migration to define activity as a markdown field
berinhard May 26, 2021
a634e27
Update code do handle activity as markdown
berinhard May 26, 2021
b8d8740
Add missing pretend calls to admin routes test
berinhard May 26, 2021
a3eb825
Fix flake8 lint warnings
berinhard May 26, 2021
1861123
Add new is_active flag to control sponsors display
berinhard May 26, 2021
2d51b26
Only display active sponsors
berinhard May 26, 2021
e5e5b82
Add is_active boolean to sponsors admin
berinhard May 26, 2021
a4a256d
Add feedback message after sponsor update
berinhard May 26, 2021
cea2bf1
Color logo is required by the admin
berinhard May 26, 2021
0f34b61
Do not validate footer sponsor without white logo
berinhard May 26, 2021
6b78742
Implement new view to delete a sponsor
berinhard May 28, 2021
fe4b489
Add modal to confirm sponsor before deletion
berinhard May 28, 2021
ed70823
Run make translations to fix CI
berinhard May 28, 2021
41e6ecb
Footer sponsors can be only infra sponsors as well
berinhard May 28, 2021
c75f3c1
Increase test coverage for sponsors/models.py
berinhard May 28, 2021
97b7727
100% test coverage at cli/sponsors.py
berinhard May 31, 2021
ed003db
Add simple unit test to make explicit validation done by readme lib
berinhard Jun 3, 2021
96d9d4f
Merge branch 'main' into feature/sponsors-db
ewdurbin Jun 4, 2021
69f929c
Add sponsors app to the docs
berinhard Jun 7, 2021
dd25985
Add new boolean flag is_psf_staff to user model
berinhard Jun 7, 2021
e1d9e20
Introduce PSF Staff group and permission
berinhard Jun 7, 2021
3c13356
Configure permissions considering PSF staff members
berinhard Jun 7, 2021
36d957a
Use SQL false function instead
berinhard Jun 7, 2021
6bae6c3
Refactor permissions introducing a base one to guarantee admin access
berinhard Jun 7, 2021
384278a
Rename admin dashboard access permission
berinhard Jun 8, 2021
529f0f1
Merge branch 'main' into feature/sponsors-db
ewdurbin Jun 8, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
.coverage
.state
.idea
.envrc

docs/_build/
build/
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ initdb:
xz -d -f -k dev/$(DB).sql.xz --stdout | docker-compose run --rm web psql -h db -d warehouse -U postgres -v ON_ERROR_STOP=1 -1 -f -
docker-compose run --rm web python -m warehouse db upgrade head
$(MAKE) reindex
docker-compose run web python -m warehouse sponsors populate-db
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a plan to run this in production?

As an aside, this is a lot of work for something we only need once. Wow!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this will be run then axed.


reindex:
docker-compose run --rm web python -m warehouse search reindex
Expand Down
1 change: 1 addition & 0 deletions docs/application.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ Directories within the repository:
- `rss/ <https://github.com/pypa/warehouse/tree/master/warehouse/rss>`_ - RSS feeds: :doc:`api-reference/feeds`
- `search/ <https://github.com/pypa/warehouse/tree/master/warehouse/search>`_ - utilities for building and querying the search index
- `sitemap/ <https://github.com/pypa/warehouse/tree/master/warehouse/sitemap>`_ - site maps
- `sponsors/ <https://github.com/pypa/warehouse/tree/master/warehouse/sponsors>`_ - sponsors management
- `templates/ <https://github.com/pypa/warehouse/tree/master/warehouse/templates>`_ - Jinja templates for web pages, emails, etc.
- `utils/ <https://github.com/pypa/warehouse/tree/master/warehouse/utils>`_ - various utilities Warehouse uses

Expand Down
1 change: 1 addition & 0 deletions requirements/main.in
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ sentry-sdk
setuptools
sqlalchemy>=0.9,<1.4.0 # https://github.com/pypa/warehouse/pull/9228
sqlalchemy-citext
sqlalchemy-utils
stdlib-list
structlog
transaction
Expand Down
8 changes: 7 additions & 1 deletion requirements/main.txt
Original file line number Diff line number Diff line change
Expand Up @@ -875,11 +875,16 @@ six==1.15.0 \
# pyopenssl
# python-dateutil
# readme-renderer
# sqlalchemy-utils
# tenacity
# webauthn
sqlalchemy-citext==1.8.0 \
--hash=sha256:a1740e693a9a334e7c8f60ae731083fe75ce6c1605bb9ca6644a6f1f63b15b77
# via -r requirements/main.in
# via -r main.in
sqlalchemy-utils==0.37.2 \
--hash=sha256:042e08454ee7b822b1e2f2b7c20f76fe7b8255de10354718a11e68ced1a64643 \
--hash=sha256:c60b8b43c9ef809d147b0bc571cfbfe0992f854ec242bc01ab7a562f76113743
# via -r main.in
sqlalchemy==1.3.23 \
--hash=sha256:040bdfc1d76a9074717a3f43455685f781c581f94472b010cd6c4754754e1862 \
--hash=sha256:1fe5d8d39118c2b018c215c37b73fd6893c3e1d4895be745ca8ff6eb83333ed3 \
Expand Down Expand Up @@ -924,6 +929,7 @@ sqlalchemy==1.3.23 \
# alembic
# paginate-sqlalchemy
# sqlalchemy-citext
# sqlalchemy-utils
# zope.sqlalchemy
stdlib-list==0.8.0 \
--hash=sha256:2ae0712a55b68f3fbbc9e58d6fa1b646a062188f49745b495f94d3310a9fdd3e \
Expand Down
1 change: 1 addition & 0 deletions tests/common/db/accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Meta:
is_active = True
is_superuser = False
is_moderator = False
is_psf_staff = False
date_joined = factory.fuzzy.FuzzyNaiveDateTime(
datetime.datetime(2005, 1, 1), datetime.datetime(2010, 1, 1)
)
Expand Down
23 changes: 23 additions & 0 deletions tests/common/db/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,26 @@ def fuzz(self):
chars = string.ascii_letters + string.digits
username = "".join(random.choice(chars) for i in range(12))
return "@".join([username, self.domain])


class FuzzyList(fuzzy.BaseFuzzyAttribute):
def __init__(self, item_factory, item_kwargs=None, size=1, *args, **kwargs):
super().__init__(*args, **kwargs)
self.item_factory = item_factory
self.item_kwargs = item_kwargs or {}
self.size = size

def fuzz(self):
return [self.item_factory(**self.item_kwargs).fuzz() for i in range(self.size)]


class FuzzyUrl(fuzzy.BaseFuzzyAttribute):
def __init__(self, domain="example.com", is_secure=False, *args, **kwargs):
super().__init__(*args, **kwargs)
self.domain = domain
self.protocol = "https" if is_secure else "http"

def fuzz(self):
chars = string.ascii_letters
path = "".join(random.choice(chars) for i in range(12))
return f"{self.protocol}://{self.domain}/{path}"
37 changes: 37 additions & 0 deletions tests/common/db/sponsors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from factory import fuzzy

from warehouse.sponsors.models import Sponsor

from .base import FuzzyUrl, WarehouseFactory


class SponsorFactory(WarehouseFactory):
class Meta:
model = Sponsor

name = fuzzy.FuzzyText(length=12)
service = fuzzy.FuzzyText(length=12)
activity_markdown = fuzzy.FuzzyText(length=12)

link_url = FuzzyUrl()
color_logo_url = FuzzyUrl()
white_logo_url = FuzzyUrl()

is_active = True
footer = True
psf_sponsor = True
infra_sponsor = False
one_time = False
sidebar = True
59 changes: 52 additions & 7 deletions tests/unit/accounts/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,16 +227,61 @@ def test_via_basic_auth_compromised(

class TestAuthenticate:
@pytest.mark.parametrize(
("is_superuser", "is_moderator", "expected"),
("is_superuser", "is_moderator", "is_psf_staff", "expected"),
[
(False, False, []),
(True, False, ["group:admins", "group:moderators"]),
(False, True, ["group:moderators"]),
(True, True, ["group:admins", "group:moderators"]),
(False, False, False, []),
(
True,
False,
False,
[
"group:admins",
"group:moderators",
"group:psf_staff",
"group:with_admin_dashboard_access",
],
),
(
False,
True,
False,
["group:moderators", "group:with_admin_dashboard_access"],
),
(
True,
True,
False,
[
"group:admins",
"group:moderators",
"group:psf_staff",
"group:with_admin_dashboard_access",
],
),
(
False,
False,
True,
["group:psf_staff", "group:with_admin_dashboard_access"],
),
(
False,
True,
True,
[
"group:moderators",
"group:psf_staff",
"group:with_admin_dashboard_access",
],
),
],
)
def test_with_user(self, is_superuser, is_moderator, expected):
user = pretend.stub(is_superuser=is_superuser, is_moderator=is_moderator)
def test_with_user(self, is_superuser, is_moderator, is_psf_staff, expected):
user = pretend.stub(
is_superuser=is_superuser,
is_moderator=is_moderator,
is_psf_staff=is_psf_staff,
)
service = pretend.stub(get_user=pretend.call_recorder(lambda userid: user))
request = pretend.stub(find_service=lambda iface, context: service)

Expand Down
20 changes: 20 additions & 0 deletions tests/unit/admin/test_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,24 @@ def test_includeme():
"/admin/verdicts/{verdict_id}/review",
domain=warehouse,
),
pretend.call(
"admin.sponsor.list",
"/admin/sponsors/",
domain=warehouse,
),
pretend.call(
"admin.sponsor.create",
"/admin/sponsors/create/",
domain=warehouse,
),
pretend.call(
"admin.sponsor.delete",
"/admin/sponsors/{sponsor_id}/delete/",
domain=warehouse,
),
pretend.call(
"admin.sponsor.edit",
"/admin/sponsors/{sponsor_id}/",
domain=warehouse,
),
]
Loading