|
29 | 29 | from projects.model_support import SourcePluginName |
30 | 30 | from projects.models import ( |
31 | 31 | BlueskyCredentials, |
| 32 | + MastodonCredentials, |
32 | 33 | Project, |
33 | 34 | ProjectConfig, |
34 | 35 | ProjectMembership, |
@@ -760,6 +761,81 @@ def test_verify_bluesky_credentials_surfaces_verification_errors( |
760 | 761 | self.owner_project.id, |
761 | 762 | ) |
762 | 763 |
|
| 764 | + def test_verify_mastodon_credentials_requires_configured_project_credentials(self): |
| 765 | + response = self.client.post( |
| 766 | + reverse( |
| 767 | + "v1:project-verify-mastodon-credentials", |
| 768 | + kwargs={"id": self.owner_project.id}, |
| 769 | + ), |
| 770 | + format="json", |
| 771 | + ) |
| 772 | + |
| 773 | + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) |
| 774 | + self.assert_standardized_validation_error( |
| 775 | + response.json(), "mastodon_credentials" |
| 776 | + ) |
| 777 | + |
| 778 | + @patch("core.plugins.mastodon.MastodonSourcePlugin.verify_credentials") |
| 779 | + def test_verify_mastodon_credentials_verifies_project_account(self, verify_mock): |
| 780 | + credentials = MastodonCredentials( |
| 781 | + project=self.owner_project, |
| 782 | + instance_url="https://hachyderm.io", |
| 783 | + account_acct="alice@hachyderm.io", |
| 784 | + ) |
| 785 | + credentials.set_access_token("access-token") |
| 786 | + credentials.save() |
| 787 | + |
| 788 | + response = self.client.post( |
| 789 | + reverse( |
| 790 | + "v1:project-verify-mastodon-credentials", |
| 791 | + kwargs={"id": self.owner_project.id}, |
| 792 | + ), |
| 793 | + format="json", |
| 794 | + ) |
| 795 | + |
| 796 | + self.assertEqual(response.status_code, status.HTTP_200_OK) |
| 797 | + verify_mock.assert_called_once() |
| 798 | + verified_credentials = verify_mock.call_args.args[0] |
| 799 | + self.assertEqual(verified_credentials.id, credentials.id) |
| 800 | + self.assertEqual(response.json()["status"], "verified") |
| 801 | + self.assertEqual(response.json()["account_acct"], "alice@hachyderm.io") |
| 802 | + self.assertEqual(response.json()["instance_url"], "https://hachyderm.io") |
| 803 | + self.assertEqual(response.json()["last_error"], "") |
| 804 | + |
| 805 | + @patch("core.api.logger.exception") |
| 806 | + @patch( |
| 807 | + "core.plugins.mastodon.MastodonSourcePlugin.verify_credentials", |
| 808 | + side_effect=RuntimeError("bad token"), |
| 809 | + ) |
| 810 | + def test_verify_mastodon_credentials_surfaces_verification_errors( |
| 811 | + self, _verify_mock, logger_exception_mock |
| 812 | + ): |
| 813 | + credentials = MastodonCredentials( |
| 814 | + project=self.owner_project, |
| 815 | + instance_url="https://hachyderm.io", |
| 816 | + account_acct="alice@hachyderm.io", |
| 817 | + ) |
| 818 | + credentials.set_access_token("access-token") |
| 819 | + credentials.save() |
| 820 | + |
| 821 | + response = self.client.post( |
| 822 | + reverse( |
| 823 | + "v1:project-verify-mastodon-credentials", |
| 824 | + kwargs={"id": self.owner_project.id}, |
| 825 | + ), |
| 826 | + format="json", |
| 827 | + ) |
| 828 | + |
| 829 | + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) |
| 830 | + self.assert_standardized_validation_error( |
| 831 | + response.json(), "mastodon_credentials" |
| 832 | + ) |
| 833 | + self.assertNotIn("bad token", str(response.json())) |
| 834 | + logger_exception_mock.assert_called_once_with( |
| 835 | + "Mastodon credential verification failed for project id=%s", |
| 836 | + self.owner_project.id, |
| 837 | + ) |
| 838 | + |
763 | 839 | @patch("core.signals.queue_topic_centroid_recompute") |
764 | 840 | def test_feedback_create_assigns_current_user(self, queue_centroid_mock): |
765 | 841 | response = self.client.post( |
@@ -918,6 +994,10 @@ def test_authenticated_nested_list_endpoints_smoke(self): |
918 | 994 | "v1:project-bluesky-credentials-list", |
919 | 995 | kwargs={"project_id": self.owner_project.id}, |
920 | 996 | ), |
| 997 | + reverse( |
| 998 | + "v1:project-mastodon-credentials-list", |
| 999 | + kwargs={"project_id": self.owner_project.id}, |
| 1000 | + ), |
921 | 1001 | reverse( |
922 | 1002 | "v1:project-intake-allowlist-list", |
923 | 1003 | kwargs={"project_id": self.owner_project.id}, |
|
0 commit comments