From e2acb608fa7280e337f1fa91a31e5e8dca88eebf Mon Sep 17 00:00:00 2001 From: Prateek Banga Date: Thu, 21 Sep 2023 22:16:02 +0530 Subject: [PATCH] fix tests with real sms providers --- .env | 6 +- app/controllers/api/messaging.php | 102 ------------------ docker-compose.yml | 4 + .../Account/AccountCustomClientTest.php | 62 +++++++---- tests/e2e/Services/GraphQL/AccountTest.php | 22 ++-- tests/e2e/Services/GraphQL/Base.php | 14 ++- 6 files changed, 71 insertions(+), 139 deletions(-) diff --git a/.env b/.env index 189095e9e..9117fe9f3 100644 --- a/.env +++ b/.env @@ -96,4 +96,8 @@ _APP_VCS_GITHUB_CLIENT_SECRET= _APP_VCS_GITHUB_WEBHOOK_SECRET= _APP_MIGRATIONS_FIREBASE_CLIENT_ID= _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET= -_APP_ASSISTANT_OPENAI_API_KEY= \ No newline at end of file +_APP_ASSISTANT_OPENAI_API_KEY= +_APP_MESSAGE_SMS_PROVIDER_MSG91_SENDER_ID= +_APP_MESSAGE_SMS_PROVIDER_MSG91_AUTH_KEY= +_APP_MESSAGE_SMS_PROVIDER_MSG91_FROM= +_APP_MESSAGE_SMS_PROVIDER_MSG91_TO= \ No newline at end of file diff --git a/app/controllers/api/messaging.php b/app/controllers/api/messaging.php index 64da3919d..275051ecb 100644 --- a/app/controllers/api/messaging.php +++ b/app/controllers/api/messaging.php @@ -1162,108 +1162,6 @@ App::patch('/v1/messaging/providers/:id/apns') ->dynamic($provider, Response::MODEL_PROVIDER); }); -/** - * General Purpose Provider - */ -App::post('/v1/messaging/providers/general') - ->desc('Create General Provider') - ->groups(['api', 'messaging']) - ->label('audits.event', 'providers.create') - ->label('audits.resource', 'providers/{response.$id}') - ->label('scope', 'providers.write') - ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) - ->label('sdk.namespace', 'messaging') - ->label('sdk.method', 'createGeneralProvider') - ->label('sdk.description', '/docs/references/messaging/create-general-provider.md') - ->label('sdk.response.code', Response::STATUS_CODE_CREATED) - ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) - ->label('sdk.response.model', Response::MODEL_PROVIDER) - ->param('providerId', '', new CustomId(), 'Provider ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.') - ->param('provider', '', new Text(128), 'Provider Internal Name') - ->param('name', '', new Text(128), 'Provider name.') - ->param('type', '', new WhiteList(['push', 'email', 'sms']), 'Provider type.') - ->param('default', false, new Boolean(), 'Set as default provider.', true) - ->param('enabled', true, new Boolean(), 'Set as enabled.', true) - ->param('credentials', '', new JSON(), 'Provider credentials object.') - ->inject('dbForProject') - ->inject('response') - ->action(function (string $providerId, string $provider, string $name, string $type, bool $default, bool $enabled, array $credentials, Database $dbForProject, Response $response) { - $providerId = $providerId == 'unique()' ? ID::unique() : $providerId; - $provider = new Document([ - '$id' => $providerId, - 'name' => $name, - 'provider' => $provider, - 'type' => $type, - 'default' => $default, - 'enabled' => $enabled, - 'credentials' => $credentials, - ]); - - // Check if a default provider exists, if not, set this one as default - if ( - empty($dbForProject->findOne('providers', [ - Query::equal('default', [true]), - ])) - ) { - $provider->setAttribute('default', true); - } - - try { - $provider = $dbForProject->createDocument('providers', $provider); - } catch (DuplicateException) { - throw new Exception(Exception::PROVIDER_ALREADY_EXISTS, 'Provider already exists.'); - } - - $response - ->setStatusCode(Response::STATUS_CODE_CREATED) - ->dynamic($provider, Response::MODEL_PROVIDER); - }); - -App::patch('/v1/messaging/providers/:id/general') - ->desc('Update General Provider') - ->groups(['api', 'messaging']) - ->label('audits.event', 'providers.update') - ->label('audits.resource', 'providers/{response.$id}') - ->label('scope', 'providers.write') - ->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY]) - ->label('sdk.namespace', 'messaging') - ->label('sdk.method', 'updateProviderGeneral') - ->label('sdk.description', '/docs/references/messaging/update-provider-general.md') - ->label('sdk.response.code', Response::STATUS_CODE_OK) - ->label('sdk.response.type', Response::CONTENT_TYPE_JSON) - ->label('sdk.response.model', Response::MODEL_PROVIDER) - ->param('id', '', new UID(), 'Provider ID.') - ->param('name', '', new Text(128), 'Provider name.', true) - ->param('enabled', null, new Boolean(), 'Set as enabled.', true) - ->param('credentials', '', new JSON(), 'Provider credentials.', true) - ->inject('dbForProject') - ->inject('response') - ->action(function (string $id, string $name, ?bool $enabled, array $credentials, Database $dbForProject, Response $response) { - $provider = $dbForProject->getDocument('providers', $id); - - if ($provider->isEmpty()) { - throw new Exception(Exception::PROVIDER_NOT_FOUND); - } - - if (!empty($name)) { - $provider->setAttribute('name', $name); - } - - if ($enabled === true || $enabled === false) { - $provider->setAttribute('enabled', $enabled); - } - - if (!empty($credentials)) { - $provider->setAttribute('credentials', $credentials); - } - - $provider = $dbForProject->updateDocument('providers', $provider->getId(), $provider); - $dbForProject->deleteCachedDocument('providers', $provider->getId()); - - $response - ->dynamic($provider, Response::MODEL_PROVIDER); - }); - App::delete('/v1/messaging/providers/:id') ->desc('Delete Provider') ->groups(['api', 'messaging']) diff --git a/docker-compose.yml b/docker-compose.yml index ac0fcabc8..053042f81 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -186,6 +186,10 @@ services: - _APP_MIGRATIONS_FIREBASE_CLIENT_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET - _APP_ASSISTANT_OPENAI_API_KEY + - _APP_MESSAGE_SMS_PROVIDER_MSG91_SENDER_ID + - _APP_MESSAGE_SMS_PROVIDER_MSG91_AUTH_KEY + - _APP_MESSAGE_SMS_PROVIDER_MSG91_FROM + - _APP_MESSAGE_SMS_PROVIDER_MSG91_TO appwrite-realtime: entrypoint: realtime diff --git a/tests/e2e/Services/Account/AccountCustomClientTest.php b/tests/e2e/Services/Account/AccountCustomClientTest.php index 5a177146a..96f9b3774 100644 --- a/tests/e2e/Services/Account/AccountCustomClientTest.php +++ b/tests/e2e/Services/Account/AccountCustomClientTest.php @@ -7,6 +7,7 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\SideClient; +use Utopia\App; use Utopia\Database\DateTime; use Utopia\Database\Helpers\ID; use Utopia\Database\Validator\Datetime as DatetimeValidator; @@ -742,20 +743,27 @@ class AccountCustomClientTest extends Scope public function testCreatePhone(): array { - $number = '+123456789'; - $response = $this->client->call(Client::METHOD_POST, '/messaging/providers/general', \array_merge([ + $to = App::getEnv('_APP_MESSAGE_SMS_PROVIDER_MSG91_TO'); + $from = App::getEnv('_APP_MESSAGE_SMS_PROVIDER_MSG91_FROM'); + $authKey = App::getEnv('_APP_MESSAGE_SMS_PROVIDER_MSG91_AUTH_KEY'); + $senderId = App::getEnv('_APP_MESSAGE_SMS_PROVIDER_MSG91_SENDER_ID'); + + if($to === '' || $from === '' || $authKey === '' || $senderId === '') { + $this->markTestSkipped('SMS provider not configured'); + } + + $number = $to; + $response = $this->client->call(Client::METHOD_POST, '/messaging/providers/msg91', \array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], 'x-appwrite-key' => $this->getProject()['apiKey'], ]), [ 'providerId' => 'unique()', - 'name' => 'Mock', - 'provider' => 'mock', + 'name' => 'Sms provider', + 'provider' => 'msg91', 'type' => 'sms', - 'credentials' => [ - 'username' => 'username', - 'password' => 'password', - ], + 'senderId' => $senderId, + 'authKey' => $authKey, 'default' => true, ]); $this->assertEquals(201, $response['headers']['status-code']); @@ -769,7 +777,7 @@ class AccountCustomClientTest extends Scope ]), [ 'userId' => ID::unique(), 'phone' => $number, - 'from' => $number, + 'from' => $from, ]); $this->assertEquals(201, $response['headers']['status-code']); @@ -778,6 +786,7 @@ class AccountCustomClientTest extends Scope $this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['expire'])); $userId = $response['body']['userId']; + $messageId = $response['body']['$id']; /** * Test for FAILURE @@ -794,17 +803,19 @@ class AccountCustomClientTest extends Scope \sleep(5); - $smsRequest = $this->getLastRequest(); + $message = $this->client->call(Client::METHOD_GET, '/messaging/messages/' . $messageId, [ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); - $this->assertEquals('http://request-catcher:5000/mock-sms', $smsRequest['url']); - $this->assertEquals('Appwrite Mock Message Sender', $smsRequest['headers']['User-Agent']); - $this->assertEquals('username', $smsRequest['headers']['X-Username']); - $this->assertEquals('password', $smsRequest['headers']['X-Key']); - $this->assertEquals('POST', $smsRequest['method']); - $this->assertEquals('+123456789', $smsRequest['data']['from']); - $this->assertEquals($number, $smsRequest['data']['to']); + $this->assertEquals(200, $message['headers']['status-code']); + $this->assertEquals(1, $message['body']['deliveredTo']); + $this->assertEquals(0, \count($message['body']['deliveryErrors'])); - $data['token'] = $smsRequest['data']['message']; + + $data['token'] = $message['body']['data']['content']; $data['id'] = $userId; $data['number'] = $number; @@ -1013,7 +1024,7 @@ class AccountCustomClientTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'], 'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session, - ]), ['from' => '+123456789']); + ]), ['from' => App::getEnv('_APP_MESSAGE_SMS_PROVIDER_MSG91_FROM')]); $this->assertEquals(201, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); @@ -1022,10 +1033,19 @@ class AccountCustomClientTest extends Scope \sleep(2); - $smsRequest = $this->getLastRequest(); + $message = $this->client->call(Client::METHOD_GET, '/messaging/messages/' . $response['body']['$id'], [ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]); + + $this->assertEquals(200, $message['headers']['status-code']); + $this->assertEquals(1, $message['body']['deliveredTo']); + $this->assertEquals(0, \count($message['body']['deliveryErrors'])); return \array_merge($data, [ - 'token' => $smsRequest['data']['message'] + 'token' => $message['body']['data']['content'] ]); } diff --git a/tests/e2e/Services/GraphQL/AccountTest.php b/tests/e2e/Services/GraphQL/AccountTest.php index 93c6b007e..0366c2f35 100644 --- a/tests/e2e/Services/GraphQL/AccountTest.php +++ b/tests/e2e/Services/GraphQL/AccountTest.php @@ -6,6 +6,7 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\SideClient; +use Utopia\App; use Utopia\Database\Helpers\ID; class AccountTest extends Scope @@ -122,24 +123,31 @@ class AccountTest extends Scope */ public function testCreatePhoneVerification(): array { + $to = App::getEnv('_APP_MESSAGE_SMS_PROVIDER_MSG91_TO'); + $from = App::getEnv('_APP_MESSAGE_SMS_PROVIDER_MSG91_FROM'); + $authKey = App::getEnv('_APP_MESSAGE_SMS_PROVIDER_MSG91_AUTH_KEY'); + $senderId = App::getEnv('_APP_MESSAGE_SMS_PROVIDER_MSG91_SENDER_ID'); + + if($to === '' || $from === '' || $authKey === '' || $senderId === '') { + $this->markTestSkipped('SMS provider not configured'); + } + $projectId = $this->getProject()['$id']; $query = $this->getQuery(self::$CREATE_PROVIDER); $graphQLPayload = [ 'query' => $query, 'variables' => [ 'providerId' => 'unique()', - 'name' => 'Mock', - 'provider' => 'mock', + 'name' => 'Sms Provider', + 'provider' => 'msg91', 'type' => 'sms', - 'credentials' => [ - 'username' => 'username', - 'password' => 'password', - ], + 'senderId' => $senderId, + 'authKey' => $authKey, 'default' => true, ], ]; - $this->client->call(Client::METHOD_POST, '/graphql', [ + $response = $this->client->call(Client::METHOD_POST, '/graphql', [ 'content-type' => 'application/json', 'x-appwrite-project' => $projectId, 'x-appwrite-key' => $this->getProject()['apiKey'], diff --git a/tests/e2e/Services/GraphQL/Base.php b/tests/e2e/Services/GraphQL/Base.php index 44cb0a0c5..7f163fdff 100644 --- a/tests/e2e/Services/GraphQL/Base.php +++ b/tests/e2e/Services/GraphQL/Base.php @@ -1932,23 +1932,21 @@ trait Base } }' . PHP_EOL . self::$FRAGMENT_ATTRIBUTES; case self::$CREATE_PROVIDER: - return 'mutation CreateGeneralProvider( + return 'mutation createProviderMsg91( $providerId: String!, - $provider: String!, $name: String!, - $type: String!, + $senderId: String!, + $authKey: String! $default: Boolean, $enabled: Boolean, - $credentials: Json! ) { - messagingCreateGeneralProvider( + messagingCreateProviderMsg91( providerId: $providerId, - provider: $provider, name: $name, - type: $type, + senderId: $senderId, + authKey: $authKey default: $default, enabled: $enabled, - credentials: $credentials ) { _id name