added reblogged_by and favourited_by

master
Théophile Choutri 2017-04-17 11:16:00 +02:00
commit 645e2c628f
21 changed files with 588 additions and 148 deletions

View File

@ -36,10 +36,11 @@ All contributions are welcome!
* OAuth2 authentication
- Register client for token-access
- Token authentication for API usage
* Authorizing or rejecting follow requests
* Support arrays as parameter type
* Uploading media attachment
* Getting who reblogged/favourited a status
* [Streaming API](https://github.com/tootsuite/documentation/blob/master/Using-the-API/Streaming-API.md)
* [Support arrays as parameter types](https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#parameter-types)
* [Update current user](https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#updating-the-current-user)
* Fix method: [Uploading media attachment](https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#uploading-a-media-attachment)
* [Getting who reblogged/favourited a status](https://github.com/milmazz/hunter/pull/2)
* Verify each endpoint
* Improve unit tests
* Improve documentation

View File

@ -115,6 +115,30 @@ defmodule Hunter do
@spec mutes(Hunter.Client.t) :: [Hunter.Account.t]
defdelegate mutes(conn), to: Hunter.Account
@doc """
Accepts a follow request
## Parameters
* `conn` - connection credentials
* `id` - follow request id
"""
@spec accept_follow_request(Hunter.Client.t, non_neg_integer) :: boolean
defdelegate accept_follow_request(conn, id), to: Hunter.Account
@doc """
Rejects a follow request
## Parameters
* `conn` - connection credentials
* `id` - follow request id
"""
@spec reject_follow_request(Hunter.Client.t, non_neg_integer) :: boolean
defdelegate reject_follow_request(conn, id), to: Hunter.Account
## Application
@doc """

View File

@ -181,4 +181,32 @@ defmodule Hunter.Account do
def mutes(conn) do
@hunter_api.mutes(conn)
end
@doc """
Accepts a follow request
## Parameters
* `conn` - connection credentials
* `id` - follow request id
"""
@spec accept_follow_request(Hunter.Client.t, non_neg_integer) :: boolean
def accept_follow_request(conn, id) do
@hunter_api.follow_request_action(conn, id, :authorize)
end
@doc """
Rejects a follow request
## Parameters
* `conn` - connection credentials
* `id` - follow request id
"""
@spec reject_follow_request(Hunter.Client.t, non_neg_integer) :: boolean
def reject_follow_request(conn, id ) do
@hunter_api.follow_request_action(conn, id, :reject)
end
end

View File

@ -105,6 +105,23 @@ defmodule Hunter.Api do
"""
@callback mutes(conn :: Hunter.Client.t) :: [Hunter.Account.t]
@doc """
Accepts or Rejects a follow request
## Parameters
* `conn` - connection credentials
* `id` - follow request id
* `action` - action to take
## Actions
* `:authorize` - authorize a follow request
* `:reject` - reject a follow request
"""
@callback follow_request_action(conn :: Hunter.Client.t, id :: non_neg_integer, action :: atom) :: boolean
## Application
@doc """
@ -260,7 +277,7 @@ defmodule Hunter.Api do
* `id` - status identifier
"""
@callback status(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Status
@callback status(conn :: Hunter.Client.t, id :: non_neg_integer) :: Hunter.Status.t
@doc """
Destroy status

View File

@ -52,6 +52,13 @@ defmodule Hunter.Api.HTTPClient do
Poison.decode!(body, as: [%Hunter.Account{}])
end
def follow_request_action(%Hunter.Client{base_url: base_url} = conn, id, action) when action in [:authorize, :reject] do
payload = Poison.encode!(%{id: id})
%HTTPoison.Response{status_code: 200} = HTTPoison.post!(base_url <> "/api/v1/follow_requests/#{action}", payload, [{"Content-Type", "application/json"} | get_headers(conn)])
true
end
def create_app(%Hunter.Client{base_url: base_url} = conn, name, redirect_uri, scopes, website) do
payload = Poison.encode!(%{client_name: name, redirect_uris: redirect_uri, scopes: scopes, website: website})

6
test/fixtures/card_by_status.json vendored Normal file
View File

@ -0,0 +1,6 @@
{
"url": "https://github.com/milmazz/hunter",
"title": "milmazz/hunter",
"image": "https://social.lou.lt/system/preview_cards/images/000/000/378/original/34700?1491626499",
"description": "hunter - A Elixir client for Mastodon, a GNU Social compatible micro-blogging service"
}

40
test/fixtures/favourite.json vendored Normal file
View File

@ -0,0 +1,40 @@
{
"visibility": "public",
"url": "https://social.lou.lt/@FriendlyPootis/442",
"uri": "tag:social.lou.lt,2017-04-03:objectId=442:objectType=Status",
"tags": [],
"spoiler_text": "",
"sensitive": false,
"reblogs_count": 4,
"reblogged": false,
"reblog": null,
"mentions": [],
"media_attachments": [],
"in_reply_to_id": null,
"in_reply_to_account_id": null,
"id": 442,
"favourites_count": 5,
"favourited": true,
"created_at": "2017-04-03T16:22:04.286Z",
"content": "<p>les gens pensez à migrer d&apos;instance pour en aller sur une moins chargée tant que vous pouvez, plus vous attendrez plus vous aurez la flemme</p>",
"application": {
"id": null,
"client_secret": null,
"client_id": null
},
"account": {
"username": "FriendlyPootis",
"url": "https://social.lou.lt/@FriendlyPootis",
"statuses_count": 253,
"note": "fermé comme un carré, Vladimir Pootin sur YT (<a href=\"https://www.youtube.com/VladimirPootin\" rel=\"nofollow noopener\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"\">youtube.com/VladimirPootin</span><span class=\"invisible\"></span></a>)",
"locked": false,
"id": 34,
"header": "https://social.lou.lt/system/accounts/headers/000/000/034/original/b009ddb5a8ce41c1.jpg?1491228302",
"following_count": 53,
"followers_count": 62,
"display_name": "FriendlyPootis 🚉",
"created_at": "2017-04-03T13:50:06.485Z",
"avatar": "https://social.lou.lt/system/accounts/avatars/000/000/034/original/565da0399c2c26cf.jpg?1491228302",
"acct": "FriendlyPootis"
}
}

38
test/fixtures/favourites.json vendored Normal file
View File

@ -0,0 +1,38 @@
[
{
"visibility": "public",
"url": "https://mstdn.io/users/paperswelove/updates/19905",
"uri": "tag:mstdn.io,2017-04-16:objectId=421573:objectType=Status",
"tags": [],
"spoiler_text": "Distributed Systems Paper",
"sensitive": false,
"reblogs_count": 0,
"reblogged": null,
"reblog": null,
"mentions": [],
"media_attachments": [],
"in_reply_to_id": null,
"in_reply_to_account_id": null,
"id": 376262,
"favourites_count": 0,
"favourited": true,
"created_at": "2017-04-16T15:32:24.000Z",
"content": "<p>Impossibility of Distributed Consensus with One Faulty<br>Process - Fischer, Lynch, Paterson</p><p>PDF: <a href=\"https://groups.csail.mit.edu/tds/papers/Lynch/jacm85.pdf\" rel=\"nofollow noopener\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">groups.csail.mit.edu/tds/paper</span><span class=\"invisible\">s/Lynch/jacm85.pdf</span></a></p><p>The consensus problem involves an asynchronous system of processes, some of which may be unreliable. The problem is for the reliable processes to agree on a binary value. In this paper, it is shown that every protocol for this problem has the possibility of nontermination, even with only one faulty process.</p>",
"application": null,
"account": {
"username": "paperswelove",
"url": "https://mstdn.io/@paperswelove",
"statuses_count": 20,
"note": "Building Bridges Between Academia and Industry\n\n<a href=\"http://paperswelove.org\" rel=\"nofollow noopener\"><span class=\"invisible\">http://</span><span class=\"\">paperswelove.org</span><span class=\"invisible\"></span></a>\n<a href=\"http://pwlconf.org\" rel=\"nofollow noopener noopener\"><span class=\"invisible\">http://</span><span class=\"\">pwlconf.org</span><span class=\"invisible\"></span></a>",
"locked": false,
"id": 7126,
"header": "https://social.lou.lt/system/accounts/headers/000/007/126/original/missing.png?1491486258",
"following_count": 3,
"followers_count": 2,
"display_name": "Papers We Love",
"created_at": "2017-04-06T13:44:18.281Z",
"avatar": "https://social.lou.lt/system/accounts/avatars/000/007/126/original/60ecc8225809c008.png?1491486258",
"acct": "paperswelove@mstdn.io"
}
}
]

60
test/fixtures/hashtag_timeline.json vendored Normal file
View File

@ -0,0 +1,60 @@
[
{
"visibility": "public",
"url": "https://mstdn.io/users/paperswelove/updates/9954",
"uri": "tag:mstdn.io,2017-04-10:objectId=171105:objectType=Status",
"tags": [
{
"url": "https://social.lou.lt/tags/paperswelove",
"name": "paperswelove"
},
{
"url": "https://social.lou.lt/tags/compsci",
"name": "compsci"
},
{
"url": "https://social.lou.lt/tags/garbagecollection",
"name": "garbagecollection"
}
],
"spoiler_text": "",
"sensitive": false,
"reblogs_count": 0,
"reblogged": null,
"reblog": null,
"mentions": [],
"media_attachments": [
{
"url": "https://social.lou.lt/system/media_attachments/files/000/010/284/original/b0432b95264e141c.png?1491824449",
"type": "image",
"text_url": null,
"remote_url": "https://mstdn.io/system/media_attachments/files/000/009/562/original/b0432b95264e141c.png",
"preview_url": "https://social.lou.lt/system/media_attachments/files/000/010/284/small/b0432b95264e141c.png?1491824449",
"id": 10284
}
],
"in_reply_to_id": null,
"in_reply_to_account_id": null,
"id": 186397,
"favourites_count": 0,
"favourited": null,
"created_at": "2017-04-10T11:40:45.000Z",
"content": "<p>One Pass Real-Time Generational Mark-Sweep Garbage Collection - Armstrong, Virding</p><p>Link: <a href=\"http://buff.ly/2pdh7iS\" rel=\"nofollow noopener\"><span class=\"invisible\">http://</span><span class=\"\">buff.ly/2pdh7iS</span><span class=\"invisible\"></span></a> </p><p>In this paper we present a simple scheme for reclaiming data for such language classes with a single pass mark-sweep collector. We also show how the simple scheme can be modified so that the collection can be done in an incremental manner (making it suitable for real-time collection).</p><p><a href=\"https://mstdn.io/tags/garbagecollection\" class=\"mention hashtag\">#<span>garbagecollection</span></a> <a href=\"https://mstdn.io/tags/compsci\" class=\"mention hashtag\">#<span>compsci</span></a> <a href=\"https://mstdn.io/tags/paperswelove\" class=\"mention hashtag\">#<span>paperswelove</span></a></p><p> <a href=\"https://mstdn.io/media/u03CNEJZho1pvTR3q6Y\" rel=\"nofollow noopener noopener\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">mstdn.io/media/u03CNEJZho1pvTR</span><span class=\"invisible\">3q6Y</span></a></p>",
"application": null,
"account": {
"username": "paperswelove",
"url": "https://mstdn.io/@paperswelove",
"statuses_count": 8,
"note": "Building Bridges Between Academia and Industry\n\n<a href=\"http://paperswelove.org\" rel=\"nofollow noopener\"><span class=\"invisible\">http://</span><span class=\"\">paperswelove.org</span><span class=\"invisible\"></span></a>\n<a href=\"http://pwlconf.org\" rel=\"nofollow noopener noopener\"><span class=\"invisible\">http://</span><span class=\"\">pwlconf.org</span><span class=\"invisible\"></span></a>",
"locked": false,
"id": 7126,
"header": "https://social.lou.lt/system/accounts/headers/000/007/126/original/missing.png?1491486258",
"following_count": 1,
"followers_count": 1,
"display_name": "Papers We Love",
"created_at": "2017-04-06T13:44:18.281Z",
"avatar": "https://social.lou.lt/system/accounts/avatars/000/007/126/original/60ecc8225809c008.png?1491486258",
"acct": "paperswelove@mstdn.io"
}
}
]

6
test/fixtures/instance_info.json vendored Normal file
View File

@ -0,0 +1,6 @@
{
"uri": "social.lou.lt",
"title": "Loultstodon",
"email": "maxime+mastodon@melinon.fr",
"description": "Mostly French instance - <a href=\"/about/more#rules\">Read full description</a> for rules."
}

7
test/fixtures/mute.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"requested": false,
"muting": true,
"following": true,
"followed_by": false,
"blocking": false
}

21
test/fixtures/notification.json vendored Normal file
View File

@ -0,0 +1,21 @@
{
"type": "follow",
"status": null,
"id": 17476,
"created_at": "2017-04-08T12:15:53.467Z",
"account": {
"username": "paperswelove",
"url": "https://mstdn.io/@paperswelove",
"statuses_count": 8,
"note": "Building Bridges Between Academia and Industry\n\n<a href=\"http://paperswelove.org\" rel=\"nofollow noopener\"><span class=\"invisible\">http://</span><span class=\"\">paperswelove.org</span><span class=\"invisible\"></span></a>\n<a href=\"http://pwlconf.org\" rel=\"nofollow noopener noopener\"><span class=\"invisible\">http://</span><span class=\"\">pwlconf.org</span><span class=\"invisible\"></span></a>",
"locked": false,
"id": 7126,
"header": "https://social.lou.lt/system/accounts/headers/000/007/126/original/missing.png?1491486258",
"following_count": 1,
"followers_count": 1,
"display_name": "Papers We Love",
"created_at": "2017-04-06T13:44:18.281Z",
"avatar": "https://social.lou.lt/system/accounts/avatars/000/007/126/original/60ecc8225809c008.png?1491486258",
"acct": "paperswelove@mstdn.io"
}
}

23
test/fixtures/notifications.json vendored Normal file
View File

@ -0,0 +1,23 @@
[
{
"type": "follow",
"status": null,
"id": 17476,
"created_at": "2017-04-08T12:15:53.467Z",
"account": {
"username": "paperswelove",
"url": "https://mstdn.io/@paperswelove",
"statuses_count": 8,
"note": "Building Bridges Between Academia and Industry\n\n<a href=\"http://paperswelove.org\" rel=\"nofollow noopener\"><span class=\"invisible\">http://</span><span class=\"\">paperswelove.org</span><span class=\"invisible\"></span></a>\n<a href=\"http://pwlconf.org\" rel=\"nofollow noopener noopener\"><span class=\"invisible\">http://</span><span class=\"\">pwlconf.org</span><span class=\"invisible\"></span></a>",
"locked": false,
"id": 7126,
"header": "https://social.lou.lt/system/accounts/headers/000/007/126/original/missing.png?1491486258",
"following_count": 1,
"followers_count": 1,
"display_name": "Papers We Love",
"created_at": "2017-04-06T13:44:18.281Z",
"avatar": "https://social.lou.lt/system/accounts/avatars/000/007/126/original/60ecc8225809c008.png?1491486258",
"acct": "paperswelove@mstdn.io"
}
}
]

38
test/fixtures/status.json vendored Normal file
View File

@ -0,0 +1,38 @@
{
"visibility": "public",
"url": "https://mstdn.io/users/paperswelove/updates/19905",
"uri": "tag:mstdn.io,2017-04-16:objectId=421573:objectType=Status",
"tags": [],
"spoiler_text": "Distributed Systems Paper",
"sensitive": false,
"reblogs_count": 0,
"reblogged": false,
"reblog": null,
"mentions": [],
"media_attachments": [],
"in_reply_to_id": null,
"in_reply_to_account_id": null,
"id": 376262,
"favourites_count": 0,
"favourited": true,
"created_at": "2017-04-16T15:32:24.000Z",
"content": "<p>Impossibility of Distributed Consensus with One Faulty<br>Process - Fischer, Lynch, Paterson</p><p>PDF: <a href=\"https://groups.csail.mit.edu/tds/papers/Lynch/jacm85.pdf\" rel=\"nofollow noopener\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">groups.csail.mit.edu/tds/paper</span><span class=\"invisible\">s/Lynch/jacm85.pdf</span></a></p><p>The consensus problem involves an asynchronous system of processes, some of which may be unreliable. The problem is for the reliable processes to agree on a binary value. In this paper, it is shown that every protocol for this problem has the possibility of nontermination, even with only one faulty process.</p>",
"application": null,
"account": {
"username": "paperswelove",
"url": "https://mstdn.io/@paperswelove",
"statuses_count": 20,
"note": "Building Bridges Between Academia and Industry\n\n<a href=\"http://paperswelove.org\" rel=\"nofollow noopener\"><span class=\"invisible\">http://</span><span class=\"\">paperswelove.org</span><span class=\"invisible\"></span></a>\n<a href=\"http://pwlconf.org\" rel=\"nofollow noopener noopener\"><span class=\"invisible\">http://</span><span class=\"\">pwlconf.org</span><span class=\"invisible\"></span></a>",
"locked": false,
"id": 7126,
"header_static": "https://social.lou.lt/system/accounts/headers/000/007/126/original/missing.png?1491486258",
"header": "https://social.lou.lt/system/accounts/headers/000/007/126/original/missing.png?1491486258",
"following_count": 3,
"followers_count": 2,
"display_name": "Papers We Love",
"created_at": "2017-04-06T13:44:18.281Z",
"avatar_static": "https://social.lou.lt/system/accounts/avatars/000/007/126/original/60ecc8225809c008.png?1491486258",
"avatar": "https://social.lou.lt/system/accounts/avatars/000/007/126/original/60ecc8225809c008.png?1491486258",
"acct": "paperswelove@mstdn.io"
}
}

134
test/fixtures/statuses.json vendored Normal file
View File

@ -0,0 +1,134 @@
[
{
"visibility": "public",
"url": "https://social.lou.lt/@milmazz/212703",
"uri": "tag:social.lou.lt,2017-04-11:objectId=212703:objectType=Status",
"tags": [],
"spoiler_text": "",
"sensitive": false,
"reblogs_count": 1,
"reblogged": null,
"reblog": null,
"mentions": [],
"media_attachments": [],
"in_reply_to_id": null,
"in_reply_to_account_id": null,
"id": 212703,
"favourites_count": 1,
"favourited": null,
"created_at": "2017-04-11T04:55:55.778Z",
"content": "<p>New release: hunter (0.3.0): Elixir client for Mastodon, a GNU social-compatible micro-blogging service</p><p><a href=\"https://hex.pm/packages/hunter\" rel=\"nofollow noopener\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">hex.pm/packages/hunter</span><span class=\"invisible\"></span></a></p>",
"application": {
"id": null,
"client_secret": null,
"client_id": null
},
"account": {
"username": "milmazz",
"url": "https://social.lou.lt/@milmazz",
"statuses_count": 3,
"note": "",
"locked": false,
"id": 8039,
"header": "https://social.lou.lt/headers/original/missing.png",
"following_count": 4,
"followers_count": 4,
"display_name": "Milton Mazzarri",
"created_at": "2017-04-06T17:43:55.325Z",
"avatar": "https://social.lou.lt/avatars/original/missing.png",
"acct": "milmazz"
}
},
{
"visibility": "public",
"url": "https://social.lou.lt/@milmazz/118635",
"uri": "tag:social.lou.lt,2017-04-08:objectId=118635:objectType=Status",
"tags": [
{
"url": "https://social.lou.lt/tags/myelixirstatus",
"name": "myelixirstatus"
}
],
"spoiler_text": "",
"sensitive": null,
"reblogs_count": 0,
"reblogged": null,
"reblog": null,
"mentions": [],
"media_attachments": [],
"in_reply_to_id": null,
"in_reply_to_account_id": null,
"id": 118635,
"favourites_count": 1,
"favourited": null,
"created_at": "2017-04-08T04:41:38.643Z",
"content": "<p>Hunter is a Elixir client for Mastodon: <a href=\"https://github.com/milmazz/hunter\" rel=\"nofollow noopener\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">github.com/milmazz/hunter</span><span class=\"invisible\"></span></a> <a href=\"https://social.lou.lt/tags/myelixirstatus\" class=\"mention hashtag\">#<span>myelixirstatus</span></a></p>",
"application": {
"id": null,
"client_secret": null,
"client_id": null
},
"account": {
"username": "milmazz",
"url": "https://social.lou.lt/@milmazz",
"statuses_count": 3,
"note": "",
"locked": false,
"id": 8039,
"header": "https://social.lou.lt/headers/original/missing.png",
"following_count": 4,
"followers_count": 4,
"display_name": "Milton Mazzarri",
"created_at": "2017-04-06T17:43:55.325Z",
"avatar": "https://social.lou.lt/avatars/original/missing.png",
"acct": "milmazz"
}
},
{
"visibility": "public",
"url": "https://social.lou.lt/@milmazz/59144",
"uri": "tag:social.lou.lt,2017-04-06:objectId=59144:objectType=Status",
"tags": [],
"spoiler_text": "",
"sensitive": false,
"reblogs_count": 0,
"reblogged": null,
"reblog": null,
"mentions": [
{
"username": "Shutsumon",
"url": "http://tootplanet.space/@Shutsumon",
"id": 7742,
"acct": "Shutsumon@tootplanet.space"
}
],
"media_attachments": [],
"in_reply_to_id": 59042,
"in_reply_to_account_id": 7742,
"id": 59144,
"favourites_count": 0,
"favourited": null,
"created_at": "2017-04-06T18:28:59.392Z",
"content": "<p><span class=\"h-card\"><a href=\"http://tootplanet.space/@Shutsumon\" class=\"u-url mention\">@<span>Shutsumon</span></a></span> You should read &quot;How to design programs&quot; book <a href=\"http://htdp.org\" rel=\"nofollow noopener\" target=\"_blank\"><span class=\"invisible\">http://</span><span class=\"\">htdp.org</span><span class=\"invisible\"></span></a></p>",
"application": {
"id": null,
"client_secret": null,
"client_id": null
},
"account": {
"username": "milmazz",
"url": "https://social.lou.lt/@milmazz",
"statuses_count": 3,
"note": "",
"locked": false,
"id": 8039,
"header": "https://social.lou.lt/headers/original/missing.png",
"following_count": 4,
"followers_count": 4,
"display_name": "Milton Mazzarri",
"created_at": "2017-04-06T17:43:55.325Z",
"avatar": "https://social.lou.lt/avatars/original/missing.png",
"acct": "milmazz"
}
}
]

40
test/fixtures/unfavourite.json vendored Normal file
View File

@ -0,0 +1,40 @@
{
"visibility": "public",
"url": "https://social.lou.lt/@FriendlyPootis/442",
"uri": "tag:social.lou.lt,2017-04-03:objectId=442:objectType=Status",
"tags": [],
"spoiler_text": "",
"sensitive": false,
"reblogs_count": 4,
"reblogged": false,
"reblog": null,
"mentions": [],
"media_attachments": [],
"in_reply_to_id": null,
"in_reply_to_account_id": null,
"id": 442,
"favourites_count": 5,
"favourited": true,
"created_at": "2017-04-03T16:22:04.286Z",
"content": "<p>les gens pensez à migrer d&apos;instance pour en aller sur une moins chargée tant que vous pouvez, plus vous attendrez plus vous aurez la flemme</p>",
"application": {
"id": null,
"client_secret": null,
"client_id": null
},
"account": {
"username": "FriendlyPootis",
"url": "https://social.lou.lt/@FriendlyPootis",
"statuses_count": 253,
"note": "fermé comme un carré, Vladimir Pootin sur YT (<a href=\"https://www.youtube.com/VladimirPootin\" rel=\"nofollow noopener\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"\">youtube.com/VladimirPootin</span><span class=\"invisible\"></span></a>)",
"locked": false,
"id": 34,
"header": "https://social.lou.lt/system/accounts/headers/000/000/034/original/b009ddb5a8ce41c1.jpg?1491228302",
"following_count": 53,
"followers_count": 62,
"display_name": "FriendlyPootis 🚉",
"created_at": "2017-04-03T13:50:06.485Z",
"avatar": "https://social.lou.lt/system/accounts/avatars/000/000/034/original/565da0399c2c26cf.jpg?1491228302",
"acct": "FriendlyPootis"
}
}

7
test/fixtures/unmute.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"requested": false,
"muting": false,
"following": true,
"followed_by": false,
"blocking": false
}

13
test/hunter/card_test.exs Normal file
View File

@ -0,0 +1,13 @@
defmodule Hunter.CardTest do
use ExUnit.Case, async: true
alias Hunter.Card
setup do
[conn: Hunter.Client.new([base_url: "https://example.com", bearer_token: "123456"])]
end
test "verify a card associated with a status", %{conn: conn} do
assert %Card{title: "milmazz/hunter"} = Card.card_by_status(conn, 118635)
end
end

View File

@ -0,0 +1,13 @@
defmodule Hunter.InstanceTest do
use ExUnit.Case, async: true
alias Hunter.Instance
setup do
[conn: Hunter.Client.new([base_url: "https://example.com", bearer_token: "123456"])]
end
test "verify instance information", %{conn: conn} do
assert %Instance{uri: "social.lou.lt"} = Instance.instance_info(conn)
end
end

View File

@ -0,0 +1,21 @@
defmodule Hunter.NotificationTest do
use ExUnit.Case, async: true
alias Hunter.Notification
setup do
[conn: Hunter.Client.new([base_url: "https://example.com", bearer_token: "123456"])]
end
test "fetch user's notifications", %{conn: conn} do
notifications = conn |> Notification.notifications() |> List.first()
assert "paperswelove" == notifications.account["username"]
assert "follow" == notifications.type
end
test "fetch a single notification", %{conn: conn} do
notification = Notification.notification(conn, 17476)
assert "paperswelove" == notification.account["username"]
assert "follow" == notification.type
end
end

View File

@ -6,11 +6,46 @@ defmodule Hunter.Api.InMemory do
@behaviour Hunter.Api
[
%{name: :verify_credentials, arity: 1, as: %Hunter.Account{}},
%{name: :account, arity: 2, as: %Hunter.Account{}},
%{name: :block, arity: 2, as: %Hunter.Relationship{}},
%{name: :blocks, arity: 1, as: [%Hunter.Account{}]},
%{name: :card_by_status, arity: 2, as: %Hunter.Card{}},
%{name: :clear_notifications, arity: 1, as: %{}},
%{name: :create_app, arity: 5, as: %Hunter.Application{}},
%{name: :create_status, arity: 4, as: %Hunter.Status{}},
%{name: :favourite, arity: 2, as: %Hunter.Status{}},
%{name: :favourited_by, arity: 2, as: [%Hunter.Account{}]},
%{name: :favourites, arity: 1, as: [%Hunter.Status{}]},
%{name: :follow, arity: 2, as: %Hunter.Relationship{}},
%{name: :follow_by_uri, arity: 2, as: %Hunter.Account{}},
%{name: :follow_requests, arity: 1, as: [%Hunter.Account{}]},
%{name: :followers, arity: 2, as: [%Hunter.Account{}]},
%{name: :following, arity: 2, as: [%Hunter.Account{}]},
%{name: :follow_by_uri, arity: 2, as: %Hunter.Account{}}
%{name: :hashtag_timeline, arity: 3, as: [%Hunter.Status{}]},
%{name: :home_timeline, arity: 2, as: [%Hunter.Status{}]},
%{name: :instance_info, arity: 1, as: %Hunter.Instance{}},
%{name: :mute, arity: 2, as: %Hunter.Relationship{}},
%{name: :mutes, arity: 1, as: [%Hunter.Account{}]},
%{name: :notification, arity: 2, as: %Hunter.Notification{}},
%{name: :notifications, arity: 1, as: [%Hunter.Notification{}]},
%{name: :public_timeline, arity: 2, as: [%Hunter.Status{}]},
%{name: :reblog, arity: 2, as: %Hunter.Status{}},
%{name: :reblogged_by, arity: 2, as: [%Hunter.Account]},
%{name: :relationships, arity: 2, as: [%Hunter.Relationship{}]},
%{name: :report, arity: 4, as: %Hunter.Report{}},
%{name: :reports, arity: 1, as: [%Hunter.Report{}]},
%{name: :search, arity: 3, as: %Hunter.Result{}},
%{name: :search_account, arity: 2, as: [%Hunter.Account{}]},
%{name: :status, arity: 2, as: %Hunter.Status{}},
%{name: :status_context, arity: 2, as: %Hunter.Context{}},
%{name: :statuses, arity: 3, as: [%Hunter.Status{}]},
%{name: :unblock, arity: 2, as: %Hunter.Relationship{}},
%{name: :unfavourite, arity: 2, as: %Hunter.Status{}},
%{name: :unfollow, arity: 2, as: %Hunter.Relationship{}},
%{name: :unmute, arity: 2, as: %Hunter.Relationship{}},
%{name: :unreblog, arity: 2, as: %Hunter.Status{}},
%{name: :upload_media, arity: 2, as: %Hunter.Attachment{}},
%{name: :verify_credentials, arity: 1, as: %Hunter.Account{}},
]
|> Enum.map(fn %{name: name, arity: arity, as: as} ->
params = for _ <- 1..arity, do: {:_, [], nil}
@ -26,145 +61,6 @@ defmodule Hunter.Api.InMemory do
end
end)
def search_account(_, _) do
[%Hunter.Account{}]
end
def blocks(_) do
[%Hunter.Account{}]
end
def follow_requests(_) do
[%Hunter.Account{}]
end
def mutes(_) do
[%Hunter.Account{}]
end
def create_app(_, _, _, _, _) do
%Hunter.Application{}
end
def upload_media(_, _) do
%Hunter.Attachment{}
end
def relationships(_, _) do
[%Hunter.Relationship{}]
end
def follow(_, _) do
%Hunter.Relationship{}
end
def unfollow(_, _) do
%Hunter.Relationship{}
end
def block(_, _) do
%Hunter.Relationship{}
end
def unblock(_, _) do
%Hunter.Relationship{}
end
def mute(_, _) do
%Hunter.Relationship{}
end
def unmute(_, _) do
%Hunter.Relationship{}
end
def search(_, _, _) do
end
def create_status(_, _, _, _) do
end
def status(_, _) do
%Hunter.Status{}
end
def destroy_status(_, _) do
true
end
def reblog(_, _) do
%Hunter.Status{}
end
def unreblog(_, _) do
%Hunter.Status{}
end
def reblogged_by(_, _) do
[%Hunter.Account{}]
end
def favourite(_, _) do
%Hunter.Status{}
end
def unfavourite(_, _) do
%Hunter.Status{}
end
def favourites(_) do
[%Hunter.Status{}]
end
def favourited_by(_, _) do
[%Hunter.Account{}]
end
def statuses(_, _, _) do
[%Hunter.Status{}]
end
def home_timeline(_, _) do
[%Hunter.Status{}]
end
def public_timeline(_, _) do
[%Hunter.Status{}]
end
def hashtag_timeline(_, _, _) do
[%Hunter.Status{}]
end
def instance_info(_) do
%Hunter.Instance{}
end
def notifications(_) do
[%Hunter.Notification{}]
end
def notification(_, _) do
%Hunter.Notification{}
end
def clear_notifications(_) do
%{}
end
def reports(_) do
[%Hunter.Report{}]
end
def report(_, _, _, _) do
%Hunter.Report{}
end
def status_context(_, _) do
%Hunter.Context{}
end
def card_by_status(_, _) do
%Hunter.Card{}
end
def destroy_status(_, _), do: true
def follow_request_action(_, _, _), do: true
end