8000 [Translation] [Bridge][Lokalise] Fix empty keys array in PUT, DELETE … · symfony/symfony@2e51808 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2e51808

Browse files
DominicLuidoldnicolas-grekas
authored andcommitted
[Translation] [Bridge][Lokalise] Fix empty keys array in PUT, DELETE requests causing Lokalise API error
1 parent 520e31b commit 2e51808

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

src/Symfony/Component/Translation/Bridge/Lokalise/LokaliseProvider.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ public function delete(TranslatorBagInterface $translatorBag): void
129129
$keysIds += $this->getKeysIds($keysToDelete, $domain);
130130
}
131131

132+
if (!$keysIds) {
133+
return;
134+
}
135+
132136
$response = $this->client->request('DELETE', 'keys', [
133137
'json' => ['keys' => array_values($keysIds)],
134138
]);
@@ -261,6 +265,10 @@ private function updateTranslations(array $keysByDomain, TranslatorBagInterface
261265
}
262266
}
263267

268+
if (!$keysToUpdate) {
269+
return;
270+
}
271+
264272
$response = $this->client->request('PUT', 'keys', [
265273
'json' => ['keys' => $keysToUpdate],
266274
]);

src/Symfony/Component/Translation/Bridge/Lokalise/Tests/LokaliseProviderTest.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,56 @@ public function testCompleteWriteProcess()
249249
$this->assertTrue($updateProcessed, 'Translations update was not called.');
250250
}
251251

252+
public function testUpdateProcessWhenLocalTranslationsMatchLokaliseTranslations()
253+
{
254+
$getLanguagesResponse = function (string $method, string $url): ResponseInterface {
255+
$this->assertSame('GET', $method);
256+
$this->assertSame('https://api.lokalise.com/api2/projects/PROJECT_ID/languages', $url);
257+
258+
return new MockResponse(json_encode([
259+
'languages' => [
260+
['lang_iso' => 'en'],
261+
['lang_iso' => 'fr'],
262+
],
263+
]));
264+
};
265+
266+
$failOnPutRequest = function (string $method, string $url, array $options = []): void {
267+
$this->assertSame('PUT', $method);
268+
$this->assertSame('https://api.lokalise.com/api2/projects/PROJECT_ID/keys', $url);
269+
$this->assertSame(json_encode(['keys' => []]), $options['body']);
270+
271+
$this->fail('PUT request is invalid: an empty `keys` array was provided, resulting in a Lokalise API error');
272+
};
273+
274+
$mockHttpClient = (new MockHttpClient([
275+
$getLanguagesResponse,
276+
$failOnPutRequest,
277+
]))->withOptions([
278+
'base_uri' => 'https://api.lokalise.com/api2/projects/PROJECT_ID/',
279+
'headers' => ['X-Api-Token' => 'API_KEY'],
280+
]);
281+
282+
$provider = self::createProvider(
283+
$mockHttpClient,
284+
$this->getLoader(),
285+
$this->getLogger(),
286+
$this->getDefaultLocale(),
287+
'api.lokalise.com'
288+
);
289+
290+
// TranslatorBag with catalogues that do not store any message to mimic the behaviour of
291+
// Symfony\Component\Translation\Command\TranslationPushCommand when local translations and Lokalise
292+
// translations match without any changes in both translation sets
293+
$translatorBag = new TranslatorBag();
294+
$translatorBag->addCatalogue(new MessageCatalogue('en', []));
295+
$translatorBag->addCatalogue(new MessageCatalogue('fr', []));
296+
297+
$provider->write($translatorBag);
298+
299+
$this->assertSame(1, $mockHttpClient->getRequestsCount());
300+
}
301+
252302
public function testWriteGetLanguageServerError()
253303
{
254304
$getLanguagesResponse = function (string $method, string $url, array $options = []): ResponseInterface {
@@ -721,6 +771,38 @@ public function testDeleteProcess()
721771
$provider->delete($translatorBag);
722772
}
723773

774+
public function testDeleteProcessWhenLocalTranslationsMatchLokaliseTranslations()
775+
{
776+
$failOnDeleteRequest = function (string $method, string $url, array $options = []): void {
777+
$this->assertSame('DELETE', $method);
778+
$this->assertSame('https://api.lokalise.com/api2/projects/PROJECT_ID/keys', $url);
779+
$this->assertSame(json_encode(['keys' => []]), $options['body']);
780+
781+
$this->fail('DELETE request is invalid: an empty `keys` array was provided, resulting in a Lokalise API error');
782+
};
783+
784+
// TranslatorBag with catalogues that do not store any message to mimic the behaviour of
785+
// Symfony\Component\Translation\Command\TranslationPushCommand when local translations and Lokalise
786+
// translations match without any changes in both translation sets
787+
$translatorBag = new TranslatorBag();
788+
$translatorBag->addCatalogue(new MessageCatalogue('en', []));
789+
$translatorBag->addCatalogue(new MessageCatalogue('fr', []));
790+
791+
$mockHttpClient = new MockHttpClient([$failOnDeleteRequest], 'https://api.lokalise.com/api2/projects/PROJECT_ID/');
792+
793+
$provider = self::createProvider(
794+
$mockHttpClient,
795+
$this->getLoader(),
796+
$this->getLogger(),
797+
$this->getDefaultLocale(),
798+
'api.lokalise.com'
799+
);
800+
801+
$provider->delete($translatorBag);
802+
803+
$this->assertSame(0, $mockHttpClient->getRequestsCount());
804+
}
805+
724806
public static function getResponsesForOneLocaleAndOneDomain(): \Generator
725807
{
726808
$arrayLoader = new ArrayLoader();

0 commit comments

Comments
 (0)
0