From c08f4f5e9682d12052444999b229c14dfc857903 Mon Sep 17 00:00:00 2001 From: Andrey Tolpeev Date: Sat, 14 Oct 2017 01:40:19 +0700 Subject: [PATCH 1/6] Fix loading data if server urls contains trailing path --- .../create/helper/UrlFormatterImplTest.java | 22 +++++++---- .../data/CreateAccountDataManagerImpl.java | 2 +- .../account/create/helper/UrlFormatter.java | 16 +++++++- .../create/helper/UrlFormatterImpl.java | 16 +++++++- .../teamcityapp/api/RepositoryImpl.java | 38 +++++++++++++------ .../teamcityapp/api/TeamCityService.java | 2 +- .../dagger/components/RestApiComponent.java | 3 +- .../dagger/modules/RestApiModule.java | 5 ++- 8 files changed, 78 insertions(+), 26 deletions(-) diff --git a/app/src/androidTest/java/com/github/vase4kin/teamcityapp/account/create/helper/UrlFormatterImplTest.java b/app/src/androidTest/java/com/github/vase4kin/teamcityapp/account/create/helper/UrlFormatterImplTest.java index 2e0b9f83..0acaee22 100644 --- a/app/src/androidTest/java/com/github/vase4kin/teamcityapp/account/create/helper/UrlFormatterImplTest.java +++ b/app/src/androidTest/java/com/github/vase4kin/teamcityapp/account/create/helper/UrlFormatterImplTest.java @@ -33,17 +33,23 @@ public void setUp() throws Exception { } @Test - public void formatUrl() throws Exception { - assertThat(mUrlFormatter.formatUrl("https://teamcity.com"), is(equalTo("https://teamcity.com"))); - assertThat(mUrlFormatter.formatUrl("https://teamcity.com/"), is(equalTo("https://teamcity.com/"))); + public void testFormatServerUrl() throws Exception { + assertThat(mUrlFormatter.formatServerUrl("https://teamcity.com"), is(equalTo("https://teamcity.com"))); + assertThat(mUrlFormatter.formatServerUrl("https://teamcity.com/"), is(equalTo("https://teamcity.com/"))); } @Test - public void formatUrlWithPath() throws Exception { - assertThat(mUrlFormatter.formatUrl("https://teamcity.com/server"), is(equalTo("https://teamcity.com/server/"))); - assertThat(mUrlFormatter.formatUrl("https://teamcity.com/server/"), is(equalTo("https://teamcity.com/server/"))); - assertThat(mUrlFormatter.formatUrl("https://teamcity.com/server/v2"), is(equalTo("https://teamcity.com/server/v2/"))); - assertThat(mUrlFormatter.formatUrl("https://teamcity.com/server/v2/"), is(equalTo("https://teamcity.com/server/v2/"))); + public void testFormatServerUrlWithPath() throws Exception { + assertThat(mUrlFormatter.formatServerUrl("https://teamcity.com/server"), is(equalTo("https://teamcity.com/server/"))); + assertThat(mUrlFormatter.formatServerUrl("https://teamcity.com/server/"), is(equalTo("https://teamcity.com/server/"))); + assertThat(mUrlFormatter.formatServerUrl("https://teamcity.com/server/v2"), is(equalTo("https://teamcity.com/server/v2/"))); + assertThat(mUrlFormatter.formatServerUrl("https://teamcity.com/server/v2/"), is(equalTo("https://teamcity.com/server/v2/"))); + } + + @Test + public void testFormatUrl() throws Exception { + assertThat(mUrlFormatter.formatBasicUrl("/app/rest/buildTypes/id:buildType/builds?locator=locator:any"), is(equalTo("app/rest/buildTypes/id:buildType/builds?locator=locator:any"))); + assertThat(mUrlFormatter.formatBasicUrl("app/rest/buildTypes/id:buildType/builds?locator=locator:any"), is(equalTo("app/rest/buildTypes/id:buildType/builds?locator=locator:any"))); } } \ No newline at end of file diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/account/create/data/CreateAccountDataManagerImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/account/create/data/CreateAccountDataManagerImpl.java index af492d91..e72d7a10 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/account/create/data/CreateAccountDataManagerImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/account/create/data/CreateAccountDataManagerImpl.java @@ -149,7 +149,7 @@ public void onResponse(Call call, final Response response) throws IOException { @Override public void run() { if (response.isSuccessful()) { - String formattedServerUrl = mUrlFormatter.formatUrl(serverUrl); + String formattedServerUrl = mUrlFormatter.formatServerUrl(serverUrl); listener.onSuccess(formattedServerUrl); } else { listener.onFail(response.code(), response.message()); diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/account/create/helper/UrlFormatter.java b/app/src/main/java/com/github/vase4kin/teamcityapp/account/create/helper/UrlFormatter.java index bfc95458..c4f9703a 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/account/create/helper/UrlFormatter.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/account/create/helper/UrlFormatter.java @@ -16,6 +16,8 @@ package com.github.vase4kin.teamcityapp.account.create.helper; +import android.support.annotation.NonNull; + /** * Url formatter */ @@ -27,5 +29,17 @@ public interface UrlFormatter { * @param serverUrl - Server url to format * @return formatted server url */ - String formatUrl(String serverUrl); + String formatServerUrl(String serverUrl); + + /** + * Remove leading slash from url to able load data if server url contains trailing path, teamcity.com/server + *

+ * https://github.com/square/retrofit/issues/907 + *

+ * ¯\_(ツ)_/¯ + *

+ * /app/rest/buildTypes/id:buildType/builds?locator=locator:any - > app/rest/buildTypes/id:buildType/builds?locator=locator:any + */ + String formatBasicUrl(@NonNull String url); } + diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/account/create/helper/UrlFormatterImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/account/create/helper/UrlFormatterImpl.java index 7ceed0f6..233cfc68 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/account/create/helper/UrlFormatterImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/account/create/helper/UrlFormatterImpl.java @@ -17,6 +17,7 @@ package com.github.vase4kin.teamcityapp.account.create.helper; import android.net.Uri; +import android.support.annotation.NonNull; import android.text.TextUtils; /** @@ -27,7 +28,7 @@ public class UrlFormatterImpl implements UrlFormatter { /** * {@inheritDoc} */ - public String formatUrl(String serverUrl) { + public String formatServerUrl(String serverUrl) { Uri serverUri = Uri.parse(serverUrl); boolean hasNoPathSegment = TextUtils.isEmpty(serverUri.getLastPathSegment()); if (hasNoPathSegment) { @@ -39,4 +40,17 @@ public String formatUrl(String serverUrl) { return serverUri.buildUpon().appendPath("").toString(); } } + + /** + * {@inheritDoc} + */ + @Override + public String formatBasicUrl(@NonNull String url) { + // Check that url has leading slash + if (url.startsWith("/")) { + return url.replaceFirst("/", ""); + } else { + return url; + } + } } diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/api/RepositoryImpl.java b/app/src/main/java/com/github/vase4kin/teamcityapp/api/RepositoryImpl.java index 54a53063..9641f529 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/api/RepositoryImpl.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/api/RepositoryImpl.java @@ -18,6 +18,7 @@ import android.support.annotation.Nullable; +import com.github.vase4kin.teamcityapp.account.create.helper.UrlFormatter; import com.github.vase4kin.teamcityapp.agents.api.Agents; import com.github.vase4kin.teamcityapp.api.cache.CacheProviders; import com.github.vase4kin.teamcityapp.artifact.api.Files; @@ -44,10 +45,14 @@ public class RepositoryImpl implements Repository { private final TeamCityService mTeamCityService; private final CacheProviders mCacheCacheProviders; + private final UrlFormatter urlFormatter; - public RepositoryImpl(TeamCityService teamCityService, CacheProviders cacheProviders) { + public RepositoryImpl(TeamCityService teamCityService, + CacheProviders cacheProviders, + UrlFormatter urlFormatter) { this.mTeamCityService = teamCityService; this.mCacheCacheProviders = cacheProviders; + this.urlFormatter = urlFormatter; } /** @@ -73,7 +78,10 @@ public Observable listAgents(@Nullable Boolean includeDisconnected, */ @Override public Observable listBuildTypes(String url, boolean update) { - return mCacheCacheProviders.listBuildTypes(mTeamCityService.listBuildTypes(url), new DynamicKey(url), new EvictDynamicKey(update)); + return mCacheCacheProviders.listBuildTypes( + mTeamCityService.listBuildTypes(urlFormatter.formatBasicUrl(url)), + new DynamicKey(url), + new EvictDynamicKey(update)); } /** @@ -93,7 +101,7 @@ public Observable buildType(String id, boolean update) { @Override public Observable build(String url, boolean update) { return mCacheCacheProviders.build( - mTeamCityService.build(url), + mTeamCityService.build(urlFormatter.formatBasicUrl(url)), new DynamicKey(url), new EvictDynamicKey(update)); } @@ -136,7 +144,7 @@ public Observable listQueueBuilds(String fields, boolean update) { */ @Override public Observable listMoreBuilds(String url) { - return mTeamCityService.listMoreBuilds(url); + return mTeamCityService.listMoreBuilds(urlFormatter.formatBasicUrl(url)); } /** @@ -145,7 +153,7 @@ public Observable listMoreBuilds(String url) { @Override public Observable listArtifacts(String url, String locator, boolean update) { return mCacheCacheProviders.listArtifacts( - mTeamCityService.listArtifacts(url, locator), + mTeamCityService.listArtifacts(urlFormatter.formatBasicUrl(url), locator), new DynamicKey(url), new EvictDynamicKey(update)); } @@ -155,7 +163,7 @@ public Observable listArtifacts(String url, String locator, boolean updat */ @Override public Observable downloadFile(String url) { - return mTeamCityService.downloadFile(url); + return mTeamCityService.downloadFile(urlFormatter.formatBasicUrl(url)); } /** @@ -163,7 +171,10 @@ public Observable downloadFile(String url) { */ @Override public Observable listTestOccurrences(String url, boolean update) { - return mCacheCacheProviders.listTestOccurrences(mTeamCityService.listTestOccurrences(url), new DynamicKey(url), new EvictDynamicKey(update)); + return mCacheCacheProviders.listTestOccurrences( + mTeamCityService.listTestOccurrences(urlFormatter.formatBasicUrl(url)), + new DynamicKey(url), + new EvictDynamicKey(update)); } /** @@ -171,7 +182,9 @@ public Observable listTestOccurrences(String url, boolean updat */ @Override public Observable testOccurrence(String url) { - return mCacheCacheProviders.testOccurrence(mTeamCityService.testOccurrence(url), new DynamicKey(url)); + return mCacheCacheProviders.testOccurrence( + mTeamCityService.testOccurrence(urlFormatter.formatBasicUrl(url)), + new DynamicKey(url)); } /** @@ -179,7 +192,10 @@ public Observable testOccurrence(String url) { */ @Override public Observable listChanges(String url, boolean update) { - return mCacheCacheProviders.listChanges(mTeamCityService.listChanges(url), new DynamicKey(url), new EvictDynamicKey(update)); + return mCacheCacheProviders.listChanges( + mTeamCityService.listChanges(urlFormatter.formatBasicUrl(url)), + new DynamicKey(url), + new EvictDynamicKey(update)); } /** @@ -187,7 +203,7 @@ public Observable listChanges(String url, boolean update) { */ @Override public Observable change(String url) { - return mCacheCacheProviders.change(mTeamCityService.change(url), new DynamicKey(url)); + return mCacheCacheProviders.change(mTeamCityService.change(urlFormatter.formatBasicUrl(url)), new DynamicKey(url)); } /** @@ -211,6 +227,6 @@ public Observable queueBuild(Build build) { */ @Override public Observable cancelBuild(String url, BuildCancelRequest buildCancelRequest) { - return mTeamCityService.cancelBuild(url, buildCancelRequest); + return mTeamCityService.cancelBuild(urlFormatter.formatBasicUrl(url), buildCancelRequest); } } diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/api/TeamCityService.java b/app/src/main/java/com/github/vase4kin/teamcityapp/api/TeamCityService.java index 383d9e55..0dbcdde5 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/api/TeamCityService.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/api/TeamCityService.java @@ -211,7 +211,7 @@ Observable listArtifacts(@Url String url, * @return {@link Observable} with {@link com.github.vase4kin.teamcityapp.changes.api.Changes.Change} */ @Headers(APPLICATION_JSON) - @GET("/app/rest/buildTypes/id:{id}/branches?locator=policy:ALL_BRANCHES") + @GET("app/rest/buildTypes/id:{id}/branches?locator=policy:ALL_BRANCHES") Observable listBranches(@Path("id") String id); /** diff --git a/app/src/main/java/com/github/vase4kin/teamcityapp/dagger/components/RestApiComponent.java b/app/src/main/java/com/github/vase4kin/teamcityapp/dagger/components/RestApiComponent.java index 888c83fb..544e8bf9 100644 --- a/app/src/main/java/com/github/vase4kin/teamcityapp/dagger/components/RestApiComponent.java +++ b/app/src/main/java/com/github/vase4kin/teamcityapp/dagger/components/RestApiComponent.java @@ -18,6 +18,7 @@ import android.content.Context; +import com.github.vase4kin.teamcityapp.account.create.dagger.UrlFormatterModule; import com.github.vase4kin.teamcityapp.api.Repository; import com.github.vase4kin.teamcityapp.api.TeamCityService; import com.github.vase4kin.teamcityapp.dagger.modules.RestApiModule; @@ -32,7 +33,7 @@ import io.rx_cache.internal.RxCache; @UserScope -@Component(dependencies = AppComponent.class, modules = RestApiModule.class) +@Component(dependencies = AppComponent.class, modules = {RestApiModule.class, UrlFormatterModule.class}) public interface RestApiComponent { TeamCityService teamCityService(); diff --git a/app/src/prod/java/com/github/vase4kin/teamcityapp/dagger/modules/RestApiModule.java b/app/src/prod/java/com/github/vase4kin/teamcityapp/dagger/modules/RestApiModule.java index bbd5d1b0..4b5450ec 100644 --- a/app/src/prod/java/com/github/vase4kin/teamcityapp/dagger/modules/RestApiModule.java +++ b/app/src/prod/java/com/github/vase4kin/teamcityapp/dagger/modules/RestApiModule.java @@ -16,6 +16,7 @@ package com.github.vase4kin.teamcityapp.dagger.modules; +import com.github.vase4kin.teamcityapp.account.create.helper.UrlFormatter; import com.github.vase4kin.teamcityapp.api.Repository; import com.github.vase4kin.teamcityapp.api.RepositoryImpl; import com.github.vase4kin.teamcityapp.api.TeamCityService; @@ -56,7 +57,7 @@ TeamCityService provideTeamCityService(@Named(CLIENT_AUTH) OkHttpClient okHttpCl @Provides @UserScope - Repository provideRepository(TeamCityService teamCityService, CacheProviders cacheProviders) { - return new RepositoryImpl(teamCityService, cacheProviders); + Repository provideRepository(TeamCityService teamCityService, CacheProviders cacheProviders, UrlFormatter urlFormatter) { + return new RepositoryImpl(teamCityService, cacheProviders, urlFormatter); } } From 270bba947ba82d2576c500c65a0ec5c004d61f0a Mon Sep 17 00:00:00 2001 From: Andrey Tolpeev Date: Sat, 14 Oct 2017 11:34:00 +0700 Subject: [PATCH 2/6] Possible fox for installing crmod correctly --- circle.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/circle.yml b/circle.yml index 0c1c95da..1fcd1b7e 100644 --- a/circle.yml +++ b/circle.yml @@ -91,6 +91,7 @@ jobs: command: | sudo apt-get install gcc python-dev python-setuptools sudo easy_install -U pip + sudo pip uninstall crcmod sudo pip install -U crcmod - run: name: Install Gcloud From c7505c7412caa8ccfbf06d0ebb580a78d92da11e Mon Sep 17 00:00:00 2001 From: Andrey Tolpeev Date: Sat, 14 Oct 2017 12:01:46 +0700 Subject: [PATCH 3/6] Fix for uninstalling crmod --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index 1fcd1b7e..95a5787b 100644 --- a/circle.yml +++ b/circle.yml @@ -91,7 +91,7 @@ jobs: command: | sudo apt-get install gcc python-dev python-setuptools sudo easy_install -U pip - sudo pip uninstall crcmod + echo y | sudo pip uninstall crcmod sudo pip install -U crcmod - run: name: Install Gcloud From 35935395e7e5de88a2c82100aadc1b175e6d87b9 Mon Sep 17 00:00:00 2001 From: Andrey Tolpeev Date: Sat, 14 Oct 2017 13:40:32 +0700 Subject: [PATCH 4/6] Update app version badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bf5d5d3a8..f69aa25a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![License](https://img.shields.io/badge/license-Apache_2.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0) [![Circle CI](https://circleci.com/gh/vase4kin/TeamCityApp/tree/master.svg?style=shield)](https://circleci.com/gh/vase4kin/TeamCityApp/tree/master) [![codecov](https://codecov.io/gh/vase4kin/TeamCityApp/branch/master/graph/badge.svg)](https://codecov.io/gh/vase4kin/TeamCityApp) -[![Release](https://img.shields.io/badge/release-1.2.3-blue.svg)](https://github.com/vase4kin/TeamCityApp/releases/latest) +[![Release](https://img.shields.io/badge/release-1.2.5-blue.svg)](https://github.com/vase4kin/TeamCityApp/releases/latest) ``` * ) ( ) ( From eea04195e9dc90e0d37ed4deebc4196d0881b278 Mon Sep 17 00:00:00 2001 From: Andrey Tolpeev Date: Sat, 14 Oct 2017 13:41:09 +0700 Subject: [PATCH 5/6] Update version --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 3bcb0d9b..2c2fec45 100644 --- a/build.gradle +++ b/build.gradle @@ -46,8 +46,8 @@ allprojects { ext { // versions - versionCode = 34 - versionName = "1.2.4" + versionCode = 35 + versionName = "1.2.5" // sdk and tools minSdkVersion = 15 From c1d9a7693e87d8cce78277590fc041f769bb01e1 Mon Sep 17 00:00:00 2001 From: Andrey Tolpeev Date: Sat, 14 Oct 2017 15:56:31 +0700 Subject: [PATCH 6/6] Remove separator in README.MD --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2e5a934e..0d84403a 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Circle CI](https://circleci.com/gh/vase4kin/TeamCityApp/tree/master.svg?style=shield)](https://circleci.com/gh/vase4kin/TeamCityApp/tree/master) [![codecov](https://codecov.io/gh/vase4kin/TeamCityApp/branch/master/graph/badge.svg)](https://codecov.io/gh/vase4kin/TeamCityApp) [![Release](https://img.shields.io/badge/release-1.2.5-blue.svg)](https://github.com/vase4kin/TeamCityApp/releases/latest) -======= + ``` * ) ( ) (