Skip to content

[Translation] [Bridge][Lokalise] Fix empty keys array in PUT, DELETE requests causing Lokalise API error #58983

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

Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ public function delete(TranslatorBagInterface $translatorBag): void
$keysIds += $this->getKeysIds($keysToDelete, $domain);
}

if (!$keysIds) {
return;
}

$response = $this->client->request('DELETE', 'keys', [
'json' => ['keys' => array_values($keysIds)],
]);
Expand Down Expand Up @@ -261,6 +265,10 @@ private function updateTranslations(array $keysByDomain, TranslatorBagInterface
}
}

if (!$keysToUpdate) {
return;
}

$response = $this->client->request('PUT', 'keys', [
'json' => ['keys' => $keysToUpdate],
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,56 @@ public function testCompleteWriteProcess()
$this->assertTrue($updateProcessed, 'Translations update was not called.');
}

public function testUpdateProcessWhenLocalTranslationsMatchLokaliseTranslations()
{
$getLanguagesResponse = function (string $method, string $url): ResponseInterface {
$this->assertSame('GET', $method);
$this->assertSame('https://api.lokalise.com/api2/projects/PROJECT_ID/languages', $url);

return new MockResponse(json_encode([
'languages' => [
['lang_iso' => 'en'],
['lang_iso' => 'fr'],
],
]));
};

$failOnPutRequest = function (string $method, string $url, array $options = []): void {
$this->assertSame('PUT', $method);
$this->assertSame('https://api.lokalise.com/api2/projects/PROJECT_ID/keys', $url);
$this->assertSame(json_encode(['keys' => []]), $options['body']);

$this->fail('PUT request is invalid: an empty `keys` array was provided, resulting in a Lokalise API error');
};

$mockHttpClient = (new MockHttpClient([
$getLanguagesResponse,
$failOnPutRequest,
]))->withOptions([
'base_uri' => 'https://api.lokalise.com/api2/projects/PROJECT_ID/',
'headers' => ['X-Api-Token' => 'API_KEY'],
]);

$provider = self::createProvider(
$mockHttpClient,
$this->getLoader(),
$this->getLogger(),
$this->getDefaultLocale(),
'api.lokalise.com'
);

// TranslatorBag with catalogues that do not store any message to mimic the behaviour of
// Symfony\Component\Translation\Command\TranslationPushCommand when local translations and Lokalise
// translations match without any changes in both translation sets
$translatorBag = new TranslatorBag();
$translatorBag->addCatalogue(new MessageCatalogue('en', []));
$translatorBag->addCatalogue(new MessageCatalogue('fr', []));

$provider->write($translatorBag);

$this->assertSame(1, $mockHttpClient->getRequestsCount());
}

public function testWriteGetLanguageServerError()
{
$getLanguagesResponse = function (string $method, string $url, array $options = []): ResponseInterface {
Expand Down Expand Up @@ -721,6 +771,38 @@ public function testDeleteProcess()
$provider->delete($translatorBag);
}

public function testDeleteProcessWhenLocalTranslationsMatchLokaliseTranslations()
{
$failOnDeleteRequest = function (string $method, string $url, array $options = []): void {
$this->assertSame('DELETE', $method);
$this->assertSame('https://api.lokalise.com/api2/projects/PROJECT_ID/keys', $url);
$this->assertSame(json_encode(['keys' => []]), $options['body']);

$this->fail('DELETE request is invalid: an empty `keys` array was provided, resulting in a Lokalise API error');
};

// TranslatorBag with catalogues that do not store any message to mimic the behaviour of
// Symfony\Component\Translation\Command\TranslationPushCommand when local translations and Lokalise
// translations match without any changes in both translation sets
$translatorBag = new TranslatorBag();
$translatorBag->addCatalogue(new MessageCatalogue('en', []));
$translatorBag->addCatalogue(new MessageCatalogue('fr', []));

$mockHttpClient = new MockHttpClient([$failOnDeleteRequest], 'https://api.lokalise.com/api2/projects/PROJECT_ID/');

$provider = self::createProvider(
$mockHttpClient,
$this->getLoader(),
$this->getLogger(),
$this->getDefaultLocale(),
'api.lokalise.com'
);

$provider->delete($translatorBag);

$this->assertSame(0, $mockHttpClient->getRequestsCount());
}

public static function getResponsesForOneLocaleAndOneDomain(): \Generator
{
$arrayLoader = new ArrayLoader();
Expand Down
Loading