diff options
-rw-r--r-- | test/mastodon-profile-tests.el | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/test/mastodon-profile-tests.el b/test/mastodon-profile-tests.el new file mode 100644 index 0000000..ca323ea --- /dev/null +++ b/test/mastodon-profile-tests.el @@ -0,0 +1,288 @@ +;;; mastodon-profile-test.el --- Tests for mastodon-profile.el -*- lexical-binding: nil -*- + +(require 'el-mock) + +(defconst gargron-profile-json + '((id . "1") + (username . "Gargron") + (acct . "Gargron") + (display_name . "Eugen") + (locked . :json-false) + (bot . :json-false) + (discoverable . t) + (group . :json-false) + (created_at . "2016-03-16T00:00:00.000Z") + (note . "<p>Developer of Mastodon and administrator of mastodon.social. I post service announcements, development updates, and personal stuff.</p>") + (url . "https://mastodon.social/@Gargron") + (avatar . "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg") + (avatar_static . "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg") + (header . "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png") + (header_static . "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png") + (followers_count . 470905) + (following_count . 451) + (statuses_count . 70741) + (last_status_at . "2021-11-14") + (emojis . []) + (fields . [((name . "Patreon") + (value . "<a href=\"https://www.patreon.com/mastodon\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"\">patreon.com/mastodon</span><span class=\"invisible\"></span></a>") + (verified_at)) + ((name . "Homepage") + (value . "<a href=\"https://zeonfederated.com\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">zeonfederated.com</span><span class=\"invisible\"></span></a>") + (verified_at . "2019-07-15T18:29:57.191+00:00"))]))) + +(defconst ccc-profile-json + '((id . "369027") + (username . "CCC") + (acct . "CCC@social.bau-ha.us") + (display_name . "") + (locked . :json-false) + (bot . :json-false) + (discoverable . :json-false) + (group . :json-false) + (created_at . "2018-06-03T00:00:00.000Z") + (note . "<p><a href=\"https://www.ccc.de/\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"\">ccc.de/</span><span class=\"invisible\"></span></a></p>") + (url . "https://social.bau-ha.us/@CCC") + (avatar . "https://files.mastodon.social/cache/accounts/avatars/000/369/027/original/6cfeb310f40e041a.jpg") + (avatar_static . "https://files.mastodon.social/cache/accounts/avatars/000/369/027/original/6cfeb310f40e041a.jpg") + (header . "https://files.mastodon.social/cache/accounts/headers/000/369/027/original/0d20bef6131b8139.jpg") + (header_static . "https://files.mastodon.social/cache/accounts/headers/000/369/027/original/0d20bef6131b8139.jpg") + (followers_count . 2733) + (following_count . 120) + (statuses_count . 1357) + (last_status_at . "2021-11-02") + (emojis . []) + (fields . []))) + +(defconst gargon-statuses-json + `[((id . "123456789012345678") + (created_at . "2021-11-11T11:11:11.111Z") + (in_reply_to_id) + (in_reply_to_account_id) + (sensitive . :json-false) + (spoiler_text . "") + (visibility . "public") + (language) + (uri . "https://mastodon.social/users/Gargron/statuses/123456789012345678/activity") + (url . "https://mastodon.social/users/Gargron/statuses/123456789012345678/activity") + (replies_count . 0) + (reblogs_count . 0) + (favourites_count . 0) + (favourited . :json-false) + (reblogged . :json-false) + (muted . :json-false) + (bookmarked . :json-false) + (content . "<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p>") + (reblog) + (application) + (account ,@gargron-profile-json) + (media_attachments . []) + (mentions . []) + (tags . []) + (emojis . []) + (card) + (poll)) + ((id . "107279356043066700") + (created_at . "2021-11-11T00:00:00.000Z") + (in_reply_to_id) + (in_reply_to_account_id) + (sensitive . :json-false) + (spoiler_text . "") + (visibility . "public") + (language . "en") + (uri . "https://mastodon.social/users/Gargron/statuses/107279356043066700") + (url . "https://mastodon.social/@Gargron/107279356043066700") + (replies_count . 0) + (reblogs_count . 2) + (favourites_count . 0) + (favourited . :json-false) + (reblogged . :json-false) + (muted . :json-false) + (bookmarked . :json-false) + (content . "<p><span class=\"h-card\"><a href=\"https://social.bau-ha.us/@CCC\" class=\"u-url mention\">@<span>CCC</span></a></span> At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>") + (reblog) + (application + (name . "Web") + (website)) + (account ,@gargron-profile-json) + (media_attachments . []) + (mentions . [((id . "369027") + (username . "CCC") + (url . "https://social.bau-ha.us/@CCC") + (acct . "CCC@social.bau-ha.us"))]) + (tags . []) + (emojis . []) + (card) + (poll))]) + +(ert-deftest mastodon-profile--add-author-bylines () + "Should correctly format short infos about one account. + +When formatting Gargon's state we want to see +- the short description of that profile, +- the url of the avatar (yet to be loaded) +- the info attached to the name" + (with-mock + ;; Don't start any image loading: + (mock (mastodon-media--inline-images * *) => nil) + ;; Let's not do formatting as that makes it hard to not rely on + ;; window width and reflowing the text. + (mock (shr-render-region * *) => nil) + (if (version< emacs-version "27.1") + (mock (image-type-available-p 'imagemagick) => t) + (mock (image-transforms-p) => t)) + + (with-temp-buffer + (let ((mastodon-tl--show-avatars t) + (mastodon-tl--display-media-p t)) + (mastodon-profile--add-author-bylines (list gargron-profile-json))) + + (should + (equal + (buffer-substring-no-properties (point-min) (point-max)) + "\n Eugen (@Gargron)\n<p>Developer of Mastodon and administrator of mastodon.social. I post service announcements, development updates, and personal stuff.</p>\n")) + + ;; Check the avatar at pos 2 + (should + (equal + (get-text-property 2 'media-url) + "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg")) + (should + (equal + (get-text-property 2 'media-state) + 'needs-loading)) + + ;; Check the byline state + (should + (equal + (get-text-property 4 'byline) + t)) + (should + (equal + (get-text-property 4 'toot-id) + (alist-get 'id gargron-profile-json))) + (should + (equal + (get-text-property 4 'toot-json) + gargron-profile-json))))) + +(ert-deftest mastodon-profile--search-account-by-handle--removes-at () + "Should ignore a leading at-sign in user handle. + +The search will happen as if called without the \"@\"." + (with-mock + + (mock (mastodon-http--get-json + "https://instance.url/api/v1/accounts/search?q=gargron")) + + (let ((mastodon-instance-url "https://instance.url")) + ;; We don't check anything from the return value. We only care + ;; that the mocked fetch was called with the expected URL. + (mastodon-profile--search-account-by-handle "@gargron")))) + +(ert-deftest mastodon-profile--search-account-by-handle--filters-out-false-results () + "Should ignore results that don't match the searched handle." + (with-mock + (mock (mastodon-http--get-json *) + => + (vector ccc-profile-json gargron-profile-json)) + + (let ((mastodon-instance-url "https://instance.url")) + (should + (equal + (mastodon-profile--search-account-by-handle "Gargron") + gargron-profile-json))))) + +(ert-deftest mastodon-profile--search-account-by-handle--filtering-is-case-sensitive () + "Should ignore results that don't match the searched handle with exact case. + +TODO: We need to decide if this is actually desired or not." + (with-mock + (mock (mastodon-http--get-json *) => (vector gargron-profile-json)) + + (let ((mastodon-instance-url "https://instance.url")) + (should + (null + (mastodon-profile--search-account-by-handle "gargron")))))) + +(ert-deftest mastodon-profile--account-from-id--correct-url () + "Should use the expected url for looking up by account id." + (with-mock + + (mock (mastodon-http--get-json + "https://instance.url/api/v1/accounts/1234567")) + + (let ((mastodon-instance-url "https://instance.url")) + ;; We don't check anything from the return value. We only care + ;; that the mocked fetch was called with the expected URL. + (mastodon-profile--account-from-id "1234567")))) + +(ert-deftest mastodon-profile--make-author-buffer () + "Should set up the buffer as expected for the given author. + +This is a far more complicated test as the +mastodon-profile--make-author-buffer function does so much. There +is a bit too much mocking and this may be brittle but it should +help identify when things change unexpectedly. + +TODO: Consider separating the data retrieval and the actual +content generation in the function under test." + (with-mock + ;; Don't start any image loading: + (mock (mastodon-media--inline-images * *) => nil) + (if (version< emacs-version "27.1") + (mock (image-type-available-p 'imagemagick) => t) + (mock (image-transforms-p) => t)) + (mock (mastodon-http--get-json "https://instance.url/api/v1/accounts/1/statuses") + => + gargon-statuses-json) + (mock (mastodon-profile--get-statuses-pinned *) + => + []) + (mock (mastodon-profile--relationships-get "1") + => + [((id . "1") (following . :json-false) (showing_reblogs . :json-false) (notifying . :json-false) (followed_by . :json-false) (blocking . :json-false) (blocked_by . :json-false) (muting . :json-false) (muting_notifications . :json-false) (requested . :json-false) (domain_blocking . :json-false) (endorsed . :json-false) (note . ""))]) + ;; Let's not do formatting as that makes it hard to not rely on + ;; window width and reflowing the text. + (mock (shr-render-region * *) => nil) + ;; Don't perform the actual update call at the end. + ;;(mock (mastodon-tl--timeline *)) + + (let ((mastodon-tl--show-avatars t) + (mastodon-tl--display-media-p t) + (mastodon-instance-url "https://instance.url")) + (mastodon-profile--make-author-buffer gargron-profile-json) + + (should + (equal + (buffer-substring-no-properties (point-min) (point-max)) + (concat + "\n" + "[img] \n" + "Eugen\n" + "@Gargron\n" + " ------------\n" + "<p>Developer of Mastodon and administrator of mastodon.social. I post service announcements, development updates, and personal stuff.</p>\n" + "_ Patreon __ :: <a href=\"https://www.patreon.com/mastodon\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"\">patreon.com/mastodon</span><span class=\"invisible\"></span></a>_ Homepage _ :: <a href=\"https://zeonfederated.com\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">zeonfederated.com</span><span class=\"invisible\"></span></a>\n" + " ------------\n" + " TOOTS: 70741 | FOLLOWERS: 470905 | FOLLOWING: 451\n" + " ------------\n" + "\n" + " ------------\n" + " TOOTS \n" + " ------------\n" + "\n" + "<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p> \n" + " Eugen (@Gargron) 2021-11-11 12:11:11\n" + " ------------\n" + "\n" + "\n" + "<p><span class=\"h-card\"><a href=\"https://social.bau-ha.us/@CCC\" class=\"u-url mention\">@<span>CCC</span></a></span> At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p> \n" + " Eugen (@Gargron) 2021-11-11 01:00:00\n" + " ------------\n" + "\n" + ))) + + ;; Until the function gets refactored this creates a non-temp + ;; buffer with Gargron's statuses which we want to delete (if + ;; the tests succeed). + (kill-buffer)))) |