Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Test Cases for Twitter Connector APIs and Update Mock Server #112

Merged
merged 16 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
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
36 changes: 36 additions & 0 deletions ballerina/Dependencies.toml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,15 @@ dependencies = [
{org = "ballerina", name = "jballerina.java"}
]

[[package]]
org = "ballerina"
name = "lang.error"
version = "0.0.0"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "jballerina.java"}
]

[[package]]
org = "ballerina"
name = "lang.int"
Expand Down Expand Up @@ -205,6 +214,9 @@ dependencies = [
{org = "ballerina", name = "lang.value"},
{org = "ballerina", name = "observe"}
]
modules = [
{org = "ballerina", packageName = "log", moduleName = "log"}
]

[[package]]
org = "ballerina"
Expand Down Expand Up @@ -245,6 +257,9 @@ dependencies = [
{org = "ballerina", name = "io"},
{org = "ballerina", name = "jballerina.java"}
]
modules = [
{org = "ballerina", packageName = "os", moduleName = "os"}
]

[[package]]
org = "ballerina"
Expand All @@ -255,13 +270,30 @@ dependencies = [
{org = "ballerina", name = "time"}
]

[[package]]
org = "ballerina"
name = "test"
version = "0.0.0"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "jballerina.java"},
{org = "ballerina", name = "lang.array"},
{org = "ballerina", name = "lang.error"}
]
modules = [
{org = "ballerina", packageName = "test", moduleName = "test"}
]

[[package]]
org = "ballerina"
name = "time"
version = "2.4.0"
dependencies = [
{org = "ballerina", name = "jballerina.java"}
]
modules = [
{org = "ballerina", packageName = "time", moduleName = "time"}
]

[[package]]
org = "ballerina"
Expand Down Expand Up @@ -293,6 +325,10 @@ version = "4.0.0"
dependencies = [
{org = "ballerina", name = "constraint"},
{org = "ballerina", name = "http"},
{org = "ballerina", name = "log"},
{org = "ballerina", name = "os"},
{org = "ballerina", name = "test"},
{org = "ballerina", name = "time"},
{org = "ballerina", name = "url"},
{org = "ballerinai", name = "observe"}
]
Expand Down
87 changes: 87 additions & 0 deletions ballerina/tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Running Tests

## Prerequisites
You need a bearer token and a Access token from twittter(X) developer account.

To do this, refer to [Ballerina Twitter Connector](https://github.com/ballerina-platform/module-ballerinax-twitter/blob/main/ballerina/Module.md).

And You need Find Your User ID For run some of the tests.
Via This Website you can find it [Twitter ID Finder](https://twiteridfinder.com/).



vish-mv marked this conversation as resolved.
Show resolved Hide resolved
# Running Tests

There are two test environments for running the Twitter(X) connector tests. The default test environment is the mock server for Twitter API. The other test environment is the actual Twitter (X) API.

You can run the tests in either of these environments and each has its own compatible set of tests.

Test Groups | Environment
-------------|---------------------------------------------------
mock_tests | Mock server for Twitter(X) API (Defualt Environment)
live_tests | Twitter(X) API

## Running Tests in the Mock Server

To execute the tests on the mock server, ensure that the `IS_LIVE_SERVER` environment variable is either set to `false` or unset before initiating the tests.

This environment variable can be configured within the `Config.toml` file located in the tests directory or specified as an environmental variable.

#### Using a Config.toml File

Create a `Config.toml` file in the tests directory and the following content:

```toml
isLiveServer = false
```

#### Using Environment Variables

Alternatively, you can set your authentication credentials as environment variables:
If you are using linux or mac, you can use following method:
```bash
export IS_LIVE_SERVER=false
```
If you are using Windows you can use following method:
```bash
set IS_LIVE_SERVER=false
```
Then, run the following command to run the tests:

```bash
./gradlew clean test
```

## Running Tests Against Twitter(X) Live API

#### Using a Config.toml File

Create a `Config.toml` file in the tests directory and add your authentication credentials a

```toml
isLiveServer = true
token = "<your-twitter-access-token>"
userId = "<your-twitter-user-id>"
```

#### Using Environment Variables

Alternatively, you can set your authentication credentials as environment variables:
If you are using linux or mac, you can use following method:
```bash
export IS_LIVE_SERVER=true
export TWITTER_TOKEN ="<your-twitter-access-token>"
export TWITTER_USER_ID ="<your-twitter-user-id>"
```

If you are using Windows you can use following method:
```bash
setx IS_LIVE_SERVER true
setx TWITTER_TOKEN <your-twitter-access-token>
setx TWITTER_USER_ID <your-twitter-user-id>
```
Then, run the following command to run the tests:

```bash
./gradlew clean test
```
231 changes: 231 additions & 0 deletions ballerina/tests/mock_service.bal
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
// Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com).
//
// WSO2 LLC. licenses this file to you 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.


vish-mv marked this conversation as resolved.
Show resolved Hide resolved
import ballerina/http;
import ballerina/log;

listener http:Listener httpListener = new (9090);

http:Service mockService = service object {


vish-mv marked this conversation as resolved.
Show resolved Hide resolved
vish-mv marked this conversation as resolved.
Show resolved Hide resolved
# Remove a bookmarked Post
#
# + id - The ID of the authenticated source User whose bookmark is to be removed.
# + tweet_id - The ID of the Post that the source User is removing from bookmarks.
# + return - returns can be any of following types
# http:Ok (The request has succeeded.)
# http:Response (The request has failed.)
resource function delete users/[UserIdMatchesAuthenticatedUser id]/bookmarks/[TweetId tweet_id]() returns BookmarkMutationResponse|http:Response {
BookmarkMutationResponse response = {
"data":{"bookmarked":false}
};
return response;
vish-mv marked this conversation as resolved.
Show resolved Hide resolved
}



vish-mv marked this conversation as resolved.
Show resolved Hide resolved
# Causes the User (in the path) to unlike the specified Post
#
# + id - The ID of the authenticated source User that is requesting to unlike the Post.
# + tweet_id - The ID of the Post that the User is requesting to unlike.
# + return - returns can be any of following types
# http:Ok (The request has succeeded.)
# http:Response (The request has failed.)
resource function delete users/[UserIdMatchesAuthenticatedUser id]/likes/[TweetId tweet_id]() returns UsersLikesDeleteResponse|http:Response {
UsersLikesDeleteResponse response = {
"data":{"liked":false}
};
return response;
}

# Causes the User (in the path) to unretweet the specified Post
#
# + id - The ID of the authenticated source User that is requesting to repost the Post.
# + source_tweet_id - The ID of the Post that the User is requesting to unretweet.
# + return - returns can be any of following types
# http:Ok (The request has succeeded.)
# http:Response (The request has failed.)
resource function delete users/[UserIdMatchesAuthenticatedUser id]/retweets/[TweetId source_tweet_id]() returns UsersRetweetsDeleteResponse|http:Response {
UsersRetweetsDeleteResponse response = {
"data":{"retweeted":false}
};
return response;
}

# Unfollow User
#
# + source_user_id - The ID of the authenticated source User that is requesting to unfollow the target User.
# + target_user_id - The ID of the User that the source User is requesting to unfollow.
# + return - returns can be any of following types
# http:Ok (The request has succeeded.)
# http:Response (The request has failed.)
resource function delete users/[UserIdMatchesAuthenticatedUser source_user_id]/following/[UserId target_user_id]() returns UsersFollowingDeleteResponse|http:Response {
UsersFollowingDeleteResponse response = {
"data":{"following":false}
};
return response;
}

# Unmute User by User ID
#
# + source_user_id - The ID of the authenticated source User that is requesting to unmute the target User.
# + target_user_id - The ID of the User that the source User is requesting to unmute.
# + return - returns can be any of following types
# http:Ok (The request has succeeded.)
# http:Response (The request has failed.)
resource function delete users/[UserIdMatchesAuthenticatedUser source_user_id]/muting/[UserId target_user_id]() returns MuteUserMutationResponse|http:Response {
MuteUserMutationResponse response = {
"data":{"muting":false}
};
return response;
}

# Post lookup by Post ID
#
# + id - A single Post ID.
# + tweet\.fields - A comma separated list of Tweet fields to display.
# + expansions - A comma separated list of fields to expand.
# + media\.fields - A comma separated list of Media fields to display.
# + poll\.fields - A comma separated list of Poll fields to display.
# + user\.fields - A comma separated list of User fields to display.
# + place\.fields - A comma separated list of Place fields to display.
# + return - returns can be any of following types
# http:Ok (The request has succeeded.)
# http:Response (The request has failed.)
resource function get tweets/[TweetId id](("attachments"|"author_id"|"card_uri"|"context_annotations"|"conversation_id"|"created_at"|"edit_controls"|"edit_history_tweet_ids"|"entities"|"geo"|"id"|"in_reply_to_user_id"|"lang"|"non_public_metrics"|"note_tweet"|"organic_metrics"|"possibly_sensitive"|"promoted_metrics"|"public_metrics"|"referenced_tweets"|"reply_settings"|"scopes"|"source"|"text"|"username"|"withheld")[]? tweet\.fields, ("attachments.media_keys"|"attachments.media_source_tweet"|"attachments.poll_ids"|"author_id"|"edit_history_tweet_ids"|"entities.mentions.username"|"geo.place_id"|"in_reply_to_user_id"|"entities.note.mentions.username"|"referenced_tweets.id"|"referenced_tweets.id.author_id"|"author_screen_name")[]? expansions, ("alt_text"|"duration_ms"|"height"|"media_key"|"non_public_metrics"|"organic_metrics"|"preview_image_url"|"promoted_metrics"|"public_metrics"|"type"|"url"|"variants"|"width")[]? media\.fields, ("duration_minutes"|"end_datetime"|"id"|"options"|"voting_status")[]? poll\.fields, ("connection_status"|"created_at"|"description"|"entities"|"id"|"location"|"most_recent_tweet_id"|"name"|"pinned_tweet_id"|"profile_image_url"|"protected"|"public_metrics"|"receives_your_dm"|"subscription_type"|"url"|"username"|"verified"|"verified_type"|"withheld")[]? user\.fields, ("contained_within"|"country"|"country_code"|"full_name"|"geo"|"id"|"name"|"place_type")[]? place\.fields) returns Get2TweetsIdResponse|http:Response {
Get2TweetsIdResponse response = {
"data":{"edit_history_tweet_ids":["1806286701704462623"],"id":"1806286701704462623","text":"aasbcascbasjbc"}
};
return response;
}

resource function get users/'by/username/[string username](("connection_status"|"created_at"|"description"|"entities"|"id"|"location"|"most_recent_tweet_id"|"name"|"pinned_tweet_id"|"profile_image_url"|"protected"|"public_metrics"|"receives_your_dm"|"subscription_type"|"url"|"username"|"verified"|"verified_type"|"withheld")[]? user\.fields, ("most_recent_tweet_id"|"pinned_tweet_id")[]? expansions, ("attachments"|"author_id"|"card_uri"|"context_annotations"|"conversation_id"|"created_at"|"edit_controls"|"edit_history_tweet_ids"|"entities"|"geo"|"id"|"in_reply_to_user_id"|"lang"|"non_public_metrics"|"note_tweet"|"organic_metrics"|"possibly_sensitive"|"promoted_metrics"|"public_metrics"|"referenced_tweets"|"reply_settings"|"scopes"|"source"|"text"|"username"|"withheld")[]? tweet\.fields) returns Get2UsersByUsernameUsernameResponse|http:Response {
Get2UsersByUsernameUsernameResponse response = {
"data":{"id":"350224247","name":"Kumar Sangakkara","username":"KumarSanga2"}
};
return response;
}


vish-mv marked this conversation as resolved.
Show resolved Hide resolved
# Creation of a Post
#
# + return - returns can be any of following types
# http:Created (The request has succeeded.)
# http:Response (The request has failed.)
resource function post tweets(@http:Payload TweetCreateRequest payload) returns TweetCreateResponse|http:Response {
TweetCreateResponse response = {
"data":{"id":"1807808193139204482","text":"Twitter Test at[1719850035,0.227505100]","edit_history_tweet_ids":["1807808193139204482"]}
};
return response;
}


vish-mv marked this conversation as resolved.
Show resolved Hide resolved
# Add Post to Bookmarks
#
# + id - The ID of the authenticated source User for whom to add bookmarks.
# + return - returns can be any of following types
# http:Ok (The request has succeeded.)
# http:Response (The request has failed.)
resource function post users/[UserIdMatchesAuthenticatedUser id]/bookmarks(@http:Payload BookmarkAddRequest payload) returns BookmarkMutationResponse|http:Response {
BookmarkMutationResponse response ={
"data":{"bookmarked":true}
};
return response;
}


vish-mv marked this conversation as resolved.
Show resolved Hide resolved
# Follow User
#
# + id - The ID of the authenticated source User that is requesting to follow the target User.
# + return - returns can be any of following types
# http:Ok (The request has succeeded.)
# http:Response (The request has failed.)
resource function post users/[UserIdMatchesAuthenticatedUser id]/following(@http:Payload UsersFollowingCreateRequest payload) returns UsersFollowingCreateResponse|http:Response {
UsersFollowingCreateResponse response = {
"data":{"following":true,"pending_follow":false}
};
return response;
}

# Causes the User (in the path) to like the specified Post
#
# + id - The ID of the authenticated source User that is requesting to like the Post.
# + return - returns can be any of following types
# http:Ok (The request has succeeded.)
# http:Response (The request has failed.)
resource function post users/[UserIdMatchesAuthenticatedUser id]/likes(@http:Payload UsersLikesCreateRequest payload) returns UsersLikesCreateResponse|http:Response {
UsersLikesCreateResponse response = {
"data":{"liked":true}
};
return response;
}

# Mute User by User ID.
#
# + id - The ID of the authenticated source User that is requesting to mute the target User.
# + return - returns can be any of following types
# http:Ok (The request has succeeded.)
# http:Response (The request has failed.)
resource function post users/[UserIdMatchesAuthenticatedUser id]/muting(@http:Payload MuteUserRequest payload) returns MuteUserMutationResponse|http:Response {
MuteUserMutationResponse response = {
"data":{"muting":true}
};
return response;
}


vish-mv marked this conversation as resolved.
Show resolved Hide resolved
# Causes the User (in the path) to repost the specified Post.
#
# + id - The ID of the authenticated source User that is requesting to repost the Post.
# + return - returns can be any of following types
# http:Ok (The request has succeeded.)
# http:Response (The request has failed.)
resource function post users/[UserIdMatchesAuthenticatedUser id]/retweets(@http:Payload UsersRetweetsCreateRequest payload) returns UsersRetweetsCreateResponse|http:Response {
UsersRetweetsCreateResponse response ={
"data":{"retweeted":true,"rest_id":"1807808194787590411"}
};
return response;
}

# User lookup by IDs
#
# + ids - A list of User IDs, comma-separated. You can specify up to 100 IDs.
# + user\.fields - A comma separated list of User fields to display.
# + expansions - A comma separated list of fields to expand.
# + tweet\.fields - A comma separated list of Tweet fields to display.
# + return - returns can be any of following types
# http:Ok (The request has succeeded.)
# http:Response (The request has failed.)
resource function get users(UserId[] ids, ("connection_status"|"created_at"|"description"|"entities"|"id"|"location"|"most_recent_tweet_id"|"name"|"pinned_tweet_id"|"profile_image_url"|"protected"|"public_metrics"|"receives_your_dm"|"subscription_type"|"url"|"username"|"verified"|"verified_type"|"withheld")[]? user\.fields, ("most_recent_tweet_id"|"pinned_tweet_id")[]? expansions, ("attachments"|"author_id"|"card_uri"|"context_annotations"|"conversation_id"|"created_at"|"edit_controls"|"edit_history_tweet_ids"|"entities"|"geo"|"id"|"in_reply_to_user_id"|"lang"|"non_public_metrics"|"note_tweet"|"organic_metrics"|"possibly_sensitive"|"promoted_metrics"|"public_metrics"|"referenced_tweets"|"reply_settings"|"scopes"|"source"|"text"|"username"|"withheld")[]? tweet\.fields) returns Get2UsersResponse|http:Response {
Get2UsersResponse response = {
"data":[{"id":"350224247","name":"Kumar Sangakkara","username":"KumarSanga2"}]
};
return response;
}
};

function init() returns error? {
if isLiveServer {
log:printInfo("Skiping mock server initialization as the tests are running on live server");
return;
}
log:printInfo("Initiating mock server");
check httpListener.attach(mockService, "/");
check httpListener.'start();
}

vish-mv marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading