kopia lustrzana https://github.com/snarfed/bridgy-fed
rodzic
4b94b4397c
commit
56c5909b84
30
pages.py
30
pages.py
|
@ -12,12 +12,13 @@ from google.cloud.ndb.stats import KindStat
|
|||
from granary import as1, as2, atom, microformats2, rss
|
||||
import humanize
|
||||
from oauth_dropins.webutil import flask_util, logs, util
|
||||
from oauth_dropins.webutil.flask_util import error, redirect
|
||||
from oauth_dropins.webutil.flask_util import error, flash, redirect
|
||||
|
||||
import common
|
||||
from common import DOMAIN_RE
|
||||
from flask_app import app, cache
|
||||
from models import fetch_page, Follower, Object, PAGE_SIZE, PROTOCOLS
|
||||
from protocol import Protocol
|
||||
|
||||
FOLLOWERS_UI_LIMIT = 999
|
||||
|
||||
|
@ -197,6 +198,33 @@ def feed(protocol, id):
|
|||
return body, {'Content-Type': rss.CONTENT_TYPE}
|
||||
|
||||
|
||||
@app.get('/bridge-user')
|
||||
@flask_util.cached(cache, datetime.timedelta(days=1))
|
||||
def bridge_user_page():
|
||||
return render_template('bridge_user.html')
|
||||
|
||||
|
||||
@app.post('/bridge-user')
|
||||
def bridge_user():
|
||||
handle = request.values['handle']
|
||||
|
||||
proto, id = Protocol.for_handle(handle)
|
||||
if not proto:
|
||||
flash(f"Couldn't determine protocol for {handle}")
|
||||
return render_template('bridge_user.html'), 400
|
||||
|
||||
if not id:
|
||||
id = proto.handle_to_id(handle)
|
||||
if not id:
|
||||
flash(f"Couldn't resolve {proto.__name__} handle {handle}")
|
||||
return render_template('bridge_user.html'), 400
|
||||
|
||||
proto.get_or_create(id=id, propagate=True)
|
||||
|
||||
flash('Bridging fake:user into Bluesky. <a href="https://bsky.app/search">Try searching for them</a> in a minute!')
|
||||
return render_template('bridge_user.html')
|
||||
|
||||
|
||||
def fetch_objects(query):
|
||||
"""Fetches a page of Object entities from a datastore query.
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<p class="row big">Enter a user to bridge</p>
|
||||
<p class="row">May be a web site domain or <code>@user@server</code> fediverse address. Bridgy Fed will federate the user into the <a href="https://atproto.com/blog/federation-developer-sandbox">Bluesky sandbox</a>.</p>
|
||||
|
||||
<div class="row big">
|
||||
<form method="post" action=""> <!-- empty action means post to same URL -->
|
||||
<input required name="handle" id="handle" placeholder="@snarfed@mastodon.social" />
|
||||
<input type="submit" class="btn btn-default" value="OK" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -1,15 +1,23 @@
|
|||
"""Unit tests for pages.py."""
|
||||
from unittest.mock import patch
|
||||
|
||||
import arroba.server
|
||||
from flask import get_flashed_messages
|
||||
from google.cloud import ndb
|
||||
from google.cloud.tasks_v2.types import Task
|
||||
from granary import atom, microformats2, rss
|
||||
from oauth_dropins.webutil import util
|
||||
from oauth_dropins.webutil.appengine_config import tasks_client
|
||||
from oauth_dropins.webutil.testutil import requests_response
|
||||
|
||||
# import first so that Fake is defined before URL routes are registered
|
||||
from .testutil import Fake, TestCase, ACTOR, COMMENT, MENTION, NOTE
|
||||
|
||||
from activitypub import ActivityPub
|
||||
from models import Object, Follower
|
||||
from models import Object, Follower, Target
|
||||
from web import Web
|
||||
|
||||
from granary.tests.test_bluesky import ACTOR_AS, ACTOR_PROFILE_VIEW_BSKY
|
||||
from .test_web import ACTOR_AS2, REPOST_AS2
|
||||
|
||||
ACTOR_WITH_PREFERRED_USERNAME = {
|
||||
|
@ -311,6 +319,41 @@ class PagesTest(TestCase):
|
|||
# COMMENT's author
|
||||
self.assertIn('Dr. Eve', got.text)
|
||||
|
||||
@patch.object(tasks_client, 'create_task', return_value=Task(name='my task'))
|
||||
@patch('requests.post',
|
||||
return_value=requests_response('OK')) # create DID on PLC
|
||||
def test_bridge_user(self, mock_post, mock_create_task):
|
||||
Fake.fetchable = {'fake:user': ACTOR_AS}
|
||||
|
||||
got = self.client.post('/bridge-user', data={'handle': 'fake:handle:user'})
|
||||
self.assertEqual(200, got.status_code)
|
||||
self.assertEqual(
|
||||
['Bridging fake:user into Bluesky. <a href="https://bsky.app/search">Try searching for them</a> in a minute!'],
|
||||
get_flashed_messages())
|
||||
|
||||
# check user, repo
|
||||
user = Fake.get_by_id('fake:user')
|
||||
self.assertEqual('fake:handle:user', user.handle)
|
||||
self.assertEqual([Target(uri=user.atproto_did, protocol='atproto')],
|
||||
user.copies)
|
||||
repo = arroba.server.storage.load_repo(user.atproto_did)
|
||||
|
||||
# check profile
|
||||
profile = repo.get_record('app.bsky.actor.profile', 'self')
|
||||
self.assertEqual(ACTOR_PROFILE_VIEW_BSKY, profile)
|
||||
|
||||
at_uri = f'at://{user.atproto_did}/app.bsky.actor.profile/self'
|
||||
self.assertEqual([Target(uri=at_uri, protocol='atproto')],
|
||||
Object.get_by_id(id='fake:user').copies)
|
||||
|
||||
mock_create_task.assert_called()
|
||||
|
||||
def test_bridge_user_bad_handle(self):
|
||||
got = self.client.post('/bridge-user', data={'handle': 'bad xyz'})
|
||||
self.assertEqual(400, got.status_code)
|
||||
self.assertEqual(["Couldn't determine protocol for bad xyz"],
|
||||
get_flashed_messages())
|
||||
|
||||
def test_nodeinfo(self):
|
||||
# just check that it doesn't crash
|
||||
self.client.get('/nodeinfo.json')
|
||||
|
|
Ładowanie…
Reference in New Issue