app: remove last pieces of AddFeed.
authorDa Risk <da_risk@geekorum.com>
Wed, 26 Jun 2019 17:35:58 -0700
changeset 317 9c8e517ce2c5
parent 316 b385702a982b
child 318 2fbcca748f78
app: remove last pieces of AddFeed. Now AddFeed functionality is totaly in the manage_feeds feature module
app/src/androidTest/java/com/geekorum/ttrss/AddFeedActivityTest.kt
app/src/androidTest/java/com/geekorum/ttrss/add_feed/AddFeedWorkerTest.kt
app/src/main/AndroidManifest.xml
app/src/main/java/com/geekorum/ttrss/add_feed/AddFeedActivity.kt
app/src/main/java/com/geekorum/ttrss/add_feed/AddFeedLauncherActivity.kt
app/src/main/java/com/geekorum/ttrss/add_feed/AddFeedViewModel.kt
app/src/main/java/com/geekorum/ttrss/add_feed/AddFeedWorker.kt
app/src/main/java/com/geekorum/ttrss/add_feed/SubscribeToFeedService.kt
app/src/main/java/com/geekorum/ttrss/add_feed/di.kt
app/src/main/java/com/geekorum/ttrss/background_job/BackgroundJobManager.kt
app/src/main/res/layout/activity_add_feed.xml
app/src/main/res/layout/item_choose_account.xml
app/src/main/res/values-night/colors.xml
app/src/main/res/values/colors.xml
app/src/main/res/values/strings.xml
app/src/main/res/values/styles.xml
app/src/test/java/com/geekorum/ttrss/add_feed/AddFeedViewModelTest.kt
--- a/app/src/androidTest/java/com/geekorum/ttrss/AddFeedActivityTest.kt	Wed Jun 26 17:23:17 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Geekttrss is a RSS feed reader application on the Android Platform.
- *
- * Copyright (C) 2017-2019 by Frederic-Charles Barthelery.
- *
- * This file is part of Geekttrss.
- *
- * Geekttrss is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Geekttrss is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Geekttrss.  If not, see <http://www.gnu.org/licenses/>.
- */
-package com.geekorum.ttrss
-
-import android.app.Activity
-import androidx.test.core.app.ActivityScenario
-import androidx.test.core.app.launchActivity
-import androidx.test.espresso.Espresso.onView
-import androidx.test.espresso.action.ViewActions.click
-import androidx.test.espresso.assertion.ViewAssertions.matches
-import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
-import androidx.test.espresso.matcher.ViewMatchers.withId
-import androidx.test.espresso.matcher.ViewMatchers.withText
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import com.geekorum.ttrss.add_feed.AddFeedActivity
-import com.google.common.truth.Truth.assertWithMessage
-import org.hamcrest.Matchers.allOf
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-class AddFeedActivityTest {
-
-    @Test
-    fun testThatWeCanLaunchTheActivity() {
-        val scenario: ActivityScenario<AddFeedActivity> = launchActivity()
-        scenario.use {
-            // remember the activity. We should not but we are explicitely testing that it is finishing
-            lateinit var currentActivity: Activity
-            scenario.onActivity {
-                currentActivity = it
-            }
-
-            // Check that the title is there
-            onView(withId(R.id.title))
-                .check(matches(
-                    allOf(withText(R.string.activity_add_feed_title),
-                        isCompletelyDisplayed()
-                    )))
-
-            // click outside
-            onView(withId(R.id.touch_outside))
-                .perform(click())
-
-            assertWithMessage("The activity should finish on outside touch")
-                .that(currentActivity.isFinishing).isTrue()
-        }
-    }
-}
--- a/app/src/androidTest/java/com/geekorum/ttrss/add_feed/AddFeedWorkerTest.kt	Wed Jun 26 17:23:17 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * Geekttrss is a RSS feed reader application on the Android Platform.
- *
- * Copyright (C) 2017-2019 by Frederic-Charles Barthelery.
- *
- * This file is part of Geekttrss.
- *
- * Geekttrss is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Geekttrss is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Geekttrss.  If not, see <http://www.gnu.org/licenses/>.
- */
-package com.geekorum.ttrss.add_feed
-
-import android.accounts.Account
-import android.content.Context
-import androidx.test.core.app.ApplicationProvider
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.work.ListenableWorker
-import androidx.work.ListenableWorker.Result
-import androidx.work.WorkerFactory
-import androidx.work.WorkerParameters
-import androidx.work.testing.TestListenableWorkerBuilder
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.runBlocking
-import org.junit.Test
-import org.junit.runner.RunWith
-import kotlin.test.BeforeTest
-
-@RunWith(AndroidJUnit4::class)
-class AddFeedWorkerTest {
-    lateinit var workerBuilder: TestListenableWorkerBuilder<AddFeedWorker>
-    private lateinit var apiService: MockApiService
-
-    @BeforeTest
-    fun setUp() {
-        val applicationContext: Context = ApplicationProvider.getApplicationContext()
-        apiService = MockApiService()
-        workerBuilder = TestListenableWorkerBuilder(applicationContext)
-        workerBuilder.setWorkerFactory(object : WorkerFactory() {
-            override fun createWorker(
-                appContext: Context, workerClassName: String, workerParameters: WorkerParameters
-            ): ListenableWorker? {
-                return AddFeedWorker(appContext, workerParameters, apiService)
-            }
-        })
-    }
-
-
-    @Test
-    fun testSuccessfulWorker() = runBlocking {
-        val inputData = AddFeedWorker.getInputData(Account("account", "type"),
-        "https://my.example.feed")
-
-        val worker = workerBuilder.setInputData(inputData).build()
-        val result = worker.startWork().get()
-        assertThat(result).isEqualTo(Result.success())
-    }
-
-    @Test
-    fun testFailingWorker() = runBlocking {
-        val inputData = AddFeedWorker.getInputData(Account("account", "type"),
-            "https://my.example.feed")
-
-        val worker = workerBuilder.setInputData(inputData).build()
-        apiService.subscribeToFeedResult = ResultCode.INVALID_URL
-        val result = worker.startWork().get()
-        assertThat(result).isEqualTo(Result.failure())
-    }
-}
-
-
-private class MockApiService : SubscribeToFeedService {
-    var subscribeToFeedResult = ResultCode.SUCCESS
-
-    override suspend fun subscribeToFeed(
-        feedUrl: String, categoryId: Long, feedLogin: String, feedPassword: String
-    ): ResultCode {
-        return subscribeToFeedResult
-    }
-}
--- a/app/src/main/AndroidManifest.xml	Wed Jun 26 17:23:17 2019 -0700
+++ b/app/src/main/AndroidManifest.xml	Wed Jun 26 17:35:58 2019 -0700
@@ -83,11 +83,6 @@
 
         <activity android:name=".settings.manage_features.InstallFeatureActivity" />
 
-        <activity android:name=".add_feed.AddFeedActivity"
-                  android:label="@string/activity_add_feed_title"
-                  android:theme="@style/AppTheme.AddFeedActivity"
-                  android:noHistory="true"/>
-
         <activity android:name=".add_feed.AddFeedLauncherActivity"
                   android:label="@string/activity_add_feed_title"
                   android:theme="@style/AppTheme.LauncherActivity">
--- a/app/src/main/java/com/geekorum/ttrss/add_feed/AddFeedActivity.kt	Wed Jun 26 17:23:17 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,175 +0,0 @@
-/*
- * Geekttrss is a RSS feed reader application on the Android Platform.
- *
- * Copyright (C) 2017-2019 by Frederic-Charles Barthelery.
- *
- * This file is part of Geekttrss.
- *
- * Geekttrss is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Geekttrss is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Geekttrss.  If not, see <http://www.gnu.org/licenses/>.
- */
-package com.geekorum.ttrss.add_feed
-
-import android.accounts.Account
-import android.content.Context
-import android.content.Intent
-import android.os.Bundle
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ArrayAdapter
-import android.widget.ImageView
-import android.widget.TextView
-import androidx.lifecycle.Observer
-import androidx.lifecycle.ViewModelProviders
-import com.geekorum.geekdroid.app.BottomSheetDialogActivity
-import com.geekorum.geekdroid.app.lifecycle.EventObserver
-import com.geekorum.geekdroid.dagger.DaggerDelegateViewModelsFactory
-import com.geekorum.ttrss.R
-import com.geekorum.ttrss.databinding.ActivityAddFeedBinding
-import com.geekorum.ttrss.htmlparsers.FeedInformation
-import dagger.android.AndroidInjection
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-import okhttp3.HttpUrl
-import java.util.concurrent.TimeUnit
-import javax.inject.Inject
-import kotlin.coroutines.CoroutineContext
-
-/**
- * Chrome share offline page as multipart/related content send in EXTRA_STREAM
- * Mime multipart can be parsed with mime4j
- * 'org.apache.james:apache-mime4j-core:0.8.1'
- * 'org.apache.james:apache-mime4j-dome:0.8.1'
- * who doesn't have much dependencies and are used by k9mail
- */
-class AddFeedActivity : BottomSheetDialogActivity(), CoroutineScope {
-    private lateinit var job: Job
-    override val coroutineContext: CoroutineContext
-        get() = Dispatchers.Main + job
-
-    @Inject
-    internal lateinit var viewModelFactory: DaggerDelegateViewModelsFactory
-
-    private lateinit var feedAdapter: FeedAdapter
-    private lateinit var accountsAdapter: AccountsAdapter
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        AndroidInjection.inject(this)
-        job = Job()
-        super.onCreate(savedInstanceState)
-
-        val viewModel = ViewModelProviders.of(this, viewModelFactory)[AddFeedViewModel::class.java]
-
-        val urlString = intent.data?.toString() ?: intent.extras?.getString(Intent.EXTRA_TEXT) ?: ""
-
-        val url = HttpUrl.parse(urlString)
-        viewModel.init(url)
-
-        val binding = ActivityAddFeedBinding.inflate(layoutInflater, null, false)
-        binding.viewModel = viewModel
-        binding.setLifecycleOwner(this)
-        setContentView(binding.root)
-
-        feedAdapter = FeedAdapter(this)
-        binding.availableFeeds.adapter = feedAdapter
-
-        accountsAdapter = AccountsAdapter(this)
-        binding.availableAccounts.adapter = accountsAdapter
-
-        viewModel.accounts.observe(this, Observer {
-            val accounts = checkNotNull(it)
-            with(accountsAdapter) {
-                clear()
-                addAll(*accounts)
-            }
-        })
-
-        viewModel.availableFeeds.observe(this, Observer {
-            val feeds = checkNotNull(it)
-            val text = feeds.firstOrNull()?.title ?: getString(R.string.activity_add_feed_no_feeds_available)
-            binding.availableFeedsSingle.text = text
-            binding.loadingProgress.hide()
-            with(feedAdapter) {
-                clear()
-                addAll(feeds)
-            }
-
-            if (feeds.isEmpty()) {
-                launch {
-                    delay(TimeUnit.MILLISECONDS.toMillis(1500))
-                    finish()
-                }
-            }
-        })
-
-        viewModel.complete.observe(this, EventObserver {
-            finish()
-        })
-    }
-
-    override fun onDestroy() {
-        super.onDestroy()
-        job.cancel()
-    }
-}
-
-private class FeedAdapter(context: Context) :
-    ArrayAdapter<FeedInformation>(context, android.R.layout.simple_dropdown_item_1line, mutableListOf()) {
-    init {
-        setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
-    }
-
-    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
-        val v = super.getView(position, convertView, parent) as TextView
-        val item = checkNotNull(getItem(position))
-        v.text = item.title
-        return v
-    }
-
-    override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
-        val v = super.getDropDownView(position, convertView, parent) as TextView
-        val item = checkNotNull(getItem(position))
-        v.text = item.title
-        return v
-    }
-}
-
-
-private class AccountsAdapter(context: Context) : ArrayAdapter<Account>(context, R.layout.item_choose_account, R.id.account_row_text, mutableListOf()) {
-    init {
-        setDropDownViewResource(R.layout.item_choose_account)
-    }
-
-    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
-        val v = super.getView(position, convertView, parent)
-        val imageView = v.findViewById<ImageView>(R.id.account_row_icon)
-        imageView.setImageResource(R.mipmap.ic_launcher)
-        val textView = v.findViewById<TextView>(R.id.account_row_text)
-        val item = checkNotNull(getItem(position))
-        textView.text = item.name
-        return v
-    }
-
-    override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
-        val v = super.getDropDownView(position, convertView, parent)
-        val imageView = v.findViewById<ImageView>(R.id.account_row_icon)
-        imageView.setImageResource(R.mipmap.ic_launcher)
-        val textView = v.findViewById<TextView>(R.id.account_row_text)
-        val item = checkNotNull(getItem(position))
-        textView.text = item.name
-        return v
-    }
-}
--- a/app/src/main/java/com/geekorum/ttrss/add_feed/AddFeedLauncherActivity.kt	Wed Jun 26 17:23:17 2019 -0700
+++ b/app/src/main/java/com/geekorum/ttrss/add_feed/AddFeedLauncherActivity.kt	Wed Jun 26 17:35:58 2019 -0700
@@ -51,8 +51,9 @@
         if (isManageFeedInstalled()) {
             try {
                 val freshContext = createPackageContext(packageName, 0)
-                val intent = intent
-                intent.component = ComponentName(freshContext, AddFeedActivity::class.java)
+                val intent = intent.apply {
+                    component = ComponentName.createRelative(freshContext, "com.geekorum.ttrss.manage_feeds.add_feed.AddFeedActivity")
+                }
                 startActivity(intent)
                 finish()
             } catch (e: PackageManager.NameNotFoundException) {
--- a/app/src/main/java/com/geekorum/ttrss/add_feed/AddFeedViewModel.kt	Wed Jun 26 17:23:17 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*
- * Geekttrss is a RSS feed reader application on the Android Platform.
- *
- * Copyright (C) 2017-2019 by Frederic-Charles Barthelery.
- *
- * This file is part of Geekttrss.
- *
- * Geekttrss is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Geekttrss is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Geekttrss.  If not, see <http://www.gnu.org/licenses/>.
- */
-package com.geekorum.ttrss.add_feed
-
-import android.accounts.Account
-import android.accounts.AccountManager
-import androidx.annotation.VisibleForTesting
-import androidx.databinding.ObservableBoolean
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.Observer
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.viewModelScope
-import com.geekorum.geekdroid.accounts.AccountsLiveData
-import com.geekorum.geekdroid.app.lifecycle.EmptyEvent
-import com.geekorum.ttrss.accounts.AccountAuthenticator
-import com.geekorum.ttrss.background_job.BackgroundJobManager
-import com.geekorum.ttrss.htmlparsers.FeedExtractor
-import com.geekorum.ttrss.htmlparsers.FeedInformation
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
-import okhttp3.HttpUrl
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import java.io.IOException
-import javax.inject.Inject
-import com.geekorum.geekdroid.app.lifecycle.EmptyEvent.Companion.makeEmptyEvent as CompleteEvent
-
-/**
- * [ViewModel] to subscribe to a Feed
- */
-class AddFeedViewModel @Inject constructor(
-    private val feedExtractor: FeedExtractor,
-    private val okHttpClient: OkHttpClient,
-    private val backgroundJobManager: BackgroundJobManager,
-    accountManager: AccountManager
-) : ViewModel() {
-
-    private val feedsInformation = MutableLiveData<List<FeedInformation>>()
-    val availableFeeds = feedsInformation as LiveData<List<FeedInformation>>
-    val accounts = AccountsLiveData(accountManager, AccountAuthenticator.TTRSS_ACCOUNT_TYPE)
-    private val _completeEvent = MutableLiveData<EmptyEvent>()
-    val complete: LiveData<EmptyEvent> = _completeEvent
-    val canSubscribe = ObservableBoolean(false)
-
-    internal var selectedFeed: FeedInformation? = null
-        set(value) {
-            field = value
-            canSubscribe.set(value != null  && selectedAccount != null)
-        }
-
-    internal var selectedAccount: Account? = null
-        set(value) {
-            field = value
-            canSubscribe.set(value != null  && selectedFeed != null)
-        }
-
-
-    private val accountObserver = Observer<Array<Account>> {
-        val accounts = checkNotNull(it)
-        selectedAccount = accounts.singleOrNull()
-    }
-
-    init {
-        accounts.observeForever(accountObserver)
-    }
-
-    override fun onCleared() {
-        super.onCleared()
-        accounts.removeObserver(accountObserver)
-    }
-
-    fun init(documentUrl: HttpUrl?) = viewModelScope.launch {
-        if (documentUrl != null) {
-            initWithUrl(documentUrl)
-        } else {
-            feedsInformation.value = emptyList()
-        }
-    }
-
-    @VisibleForTesting
-    internal suspend fun initWithUrl(documentUrl: HttpUrl) {
-        try {
-            val document = getHtmlDocument(documentUrl)
-            init(document)
-        } catch (exception: IOException) {
-            feedsInformation.value = emptyList()
-        }
-    }
-
-    fun init(document: String) {
-        feedsInformation.value = feedExtractor.extract(document).toList()
-    }
-
-    fun subscribeToFeed() {
-        val feed = checkNotNull(selectedFeed)
-        val account = checkNotNull(selectedAccount)
-        backgroundJobManager.subscribeToFeed(account, feed.href.toString(), 0, "", "")
-        _completeEvent.value = CompleteEvent()
-    }
-
-    fun cancel() {
-        _completeEvent.value = CompleteEvent()
-    }
-
-    fun setSelectedFeed(feed: Any) {
-        selectedFeed = feed as FeedInformation
-    }
-
-    fun setSelectedAccount(account: Any) {
-        selectedAccount = account as Account
-    }
-
-    private suspend fun getHtmlDocument(url: HttpUrl) = withContext(Dispatchers.IO) {
-        val request = Request.Builder().url(url).get().build()
-        val response = okHttpClient.newCall(request).execute()
-        response.use {
-            response.body()?.string() ?: ""
-        }
-    }
-}
--- a/app/src/main/java/com/geekorum/ttrss/add_feed/AddFeedWorker.kt	Wed Jun 26 17:23:17 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Geekttrss is a RSS feed reader application on the Android Platform.
- *
- * Copyright (C) 2017-2019 by Frederic-Charles Barthelery.
- *
- * This file is part of Geekttrss.
- *
- * Geekttrss is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Geekttrss is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Geekttrss.  If not, see <http://www.gnu.org/licenses/>.
- */
-package com.geekorum.ttrss.add_feed
-
-import android.accounts.Account
-import android.content.Context
-import androidx.work.CoroutineWorker
-import androidx.work.Data
-import androidx.work.ListenableWorker
-import androidx.work.WorkerFactory
-import androidx.work.WorkerParameters
-import androidx.work.workDataOf
-import com.geekorum.ttrss.network.ApiService
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.withContext
-import timber.log.Timber
-import javax.inject.Inject
-
-class AddFeedWorker(
-    contex: Context,
-    params: WorkerParameters,
-    private val apiService: SubscribeToFeedService
-) : CoroutineWorker(contex, params) {
-
-    override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
-        val feedUrl = requireNotNull(inputData.getString("url"))
-        val categoryId = inputData.getLong("categoryId", 0)
-        val feedLogin = inputData.getString("login") ?: ""
-        val feedPassword = inputData.getString("password") ?: ""
-
-        val result = apiService.subscribeToFeed(feedUrl, categoryId, feedLogin, feedPassword)
-        if (result != ResultCode.SUCCESS) {
-            Timber.e("Unable to add feed $result")
-            return@withContext Result.failure()
-        }
-        Result.success()
-    }
-
-    companion object {
-        fun getInputData(account: Account,
-                         feedUrl: String,
-                         categoryId: Long = 0,
-                         feedLogin: String = "",
-                         feedPassword: String = ""): Data {
-            return workDataOf(
-                "account_name" to account.name,
-                "account_type" to account.type,
-                "url" to feedUrl,
-                "categoryId" to categoryId,
-                "login" to feedLogin,
-                "password" to feedPassword
-            )
-        }
-    }
-
-
-    class Factory @Inject constructor(
-        private val feedComponentBuilder: AddFeedComponent.Builder
-    ) : WorkerFactory() {
-        override fun createWorker(
-            appContext: Context, workerClassName: String, workerParameters: WorkerParameters
-        ): ListenableWorker? {
-            if (workerClassName != AddFeedWorker::class.java.name) {
-                return null
-            }
-            val account = with(workerParameters.inputData) {
-                val accountName = getString("account_name")
-                val accountType = getString("account_type")
-                Account(accountName, accountType)
-            }
-
-            val addFeedComponent = feedComponentBuilder.seedAccount(account).build()
-            return AddFeedWorker(appContext, workerParameters, addFeedComponent.apiService)
-        }
-    }
-
-}
--- a/app/src/main/java/com/geekorum/ttrss/add_feed/SubscribeToFeedService.kt	Wed Jun 26 17:23:17 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Geekttrss is a RSS feed reader application on the Android Platform.
- *
- * Copyright (C) 2017-2019 by Frederic-Charles Barthelery.
- *
- * This file is part of Geekttrss.
- *
- * Geekttrss is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Geekttrss is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Geekttrss.  If not, see <http://www.gnu.org/licenses/>.
- */
-package com.geekorum.ttrss.add_feed
-
-import com.geekorum.ttrss.webapi.ApiCallException
-import com.geekorum.ttrss.webapi.RetrofitServiceHelper
-import com.geekorum.ttrss.webapi.TinyRssApi
-import com.geekorum.ttrss.webapi.TokenRetriever
-import com.geekorum.ttrss.webapi.model.SubscribeResultCode
-import com.geekorum.ttrss.webapi.model.SubscribeToFeedRequestPayload
-
-/**
- * ApiService to subscribe to a feed
- */
-interface SubscribeToFeedService {
-
-    @Throws(ApiCallException::class)
-    suspend fun subscribeToFeed(feedUrl: String, categoryId: Long = 0,
-                                feedLogin: String = "", feedPassword: String = ""): ResultCode
-}
-
-enum class ResultCode {
-    SUCCESS, INVALID_URL, UNKNOWN_ERROR
-}
-
-
-/* Implementation */
-
-internal class RetrofitSubscribeToFeedService(
-    tokenRetriever: TokenRetriever,
-    private val tinyrssApi: TinyRssApi
-) : SubscribeToFeedService {
-
-    private val helper = RetrofitServiceHelper(tokenRetriever)
-
-    override suspend fun subscribeToFeed(
-        feedUrl: String, categoryId: Long, feedLogin: String, feedPassword: String
-    ): ResultCode {
-        val payload = SubscribeToFeedRequestPayload(feedUrl, categoryId, feedLogin, feedPassword)
-        val subscribeResult = helper.executeOrFail("Unable to subscribe to feed") {
-            tinyrssApi.subscribeToFeed(payload)
-        }
-        val subscribeResultCode = subscribeResult.content.status?.let { SubscribeResultCode.valueOf(it.resultCode) }
-        return when (subscribeResultCode) {
-            SubscribeResultCode.FEED_ALREADY_EXIST, SubscribeResultCode.FEED_ADDED -> ResultCode.SUCCESS
-            SubscribeResultCode.INVALID_URL -> ResultCode.INVALID_URL
-            else -> ResultCode.UNKNOWN_ERROR
-        }
-    }
-}
--- a/app/src/main/java/com/geekorum/ttrss/add_feed/di.kt	Wed Jun 26 17:23:17 2019 -0700
+++ b/app/src/main/java/com/geekorum/ttrss/add_feed/di.kt	Wed Jun 26 17:35:58 2019 -0700
@@ -20,84 +20,15 @@
  */
 package com.geekorum.ttrss.add_feed
 
-import android.accounts.Account
-import androidx.lifecycle.ViewModel
-import androidx.work.WorkerFactory
-import com.geekorum.geekdroid.dagger.ViewModelKey
-import com.geekorum.geekdroid.dagger.WorkerInjectionModule
-import com.geekorum.geekdroid.dagger.WorkerKey
-import com.geekorum.ttrss.accounts.NetworkLoginModule
-import com.geekorum.ttrss.accounts.PerAccount
-import com.geekorum.ttrss.network.TinyrssApiModule
-import com.geekorum.ttrss.webapi.TinyRssApi
-import com.geekorum.ttrss.webapi.TokenRetriever
-import dagger.Binds
-import dagger.BindsInstance
 import dagger.Module
-import dagger.Provides
-import dagger.Subcomponent
 import dagger.android.ContributesAndroidInjector
-import dagger.multibindings.IntoMap
 
 
-/**
- * Dependency injection pieces for the Sync functionality.
- *
- * AddFeedService has a SubComponent of the ApplicationComponent, that allows it to inject to [AddFeedServicer].
- * ArticleSyncAdapter has a SubSubComponent which provides the actual SyncComponent
- *
- */
-
-@Module(includes = [WorkerInjectionModule::class, AddFeedComponentModule::class])
+@Module
 abstract class AndroidInjectorsModule {
 
-    @ContributesAndroidInjector(modules = [ViewModelsModule::class])
-    abstract fun contributeAddFeedActivityInjector(): AddFeedActivity
-
-    @ContributesAndroidInjector(modules = [ViewModelsModule::class])
+    @ContributesAndroidInjector
     abstract fun contributeAddFeedLauncherActivityInjector(): AddFeedLauncherActivity
 
-    @Binds
-    @IntoMap
-    @WorkerKey(AddFeedWorker::class)
-    abstract fun providesAddFeedWorkerFactory(workerFactory: AddFeedWorker.Factory): WorkerFactory
-
 }
 
-
-@Module(subcomponents = [AddFeedComponent::class])
-abstract class AddFeedComponentModule
-
-
-@Subcomponent(modules = [SubscribeToFeedServiceModule::class])
-@PerAccount
-interface AddFeedComponent {
-
-    val apiService: SubscribeToFeedService
-
-    @Subcomponent.Builder
-    interface Builder {
-
-        @BindsInstance
-        fun seedAccount(account: Account): Builder
-
-        fun build(): AddFeedComponent
-    }
-}
-
-@Module(includes = [TinyrssApiModule::class, NetworkLoginModule::class])
-internal class SubscribeToFeedServiceModule {
-    @Provides
-    fun providesSubscribeToFeedService(tokenRetriever: TokenRetriever, tinyrssApi: TinyRssApi): SubscribeToFeedService {
-        return RetrofitSubscribeToFeedService(tokenRetriever, tinyrssApi)
-    }
-}
-
-@Module
-private abstract class ViewModelsModule {
-    @Binds
-    @IntoMap
-    @ViewModelKey(AddFeedViewModel::class)
-    abstract fun getAddFeedViewModel(addFeedViewModel: AddFeedViewModel): ViewModel
-
-}
--- a/app/src/main/java/com/geekorum/ttrss/background_job/BackgroundJobManager.kt	Wed Jun 26 17:23:17 2019 -0700
+++ b/app/src/main/java/com/geekorum/ttrss/background_job/BackgroundJobManager.kt	Wed Jun 26 17:35:58 2019 -0700
@@ -33,11 +33,8 @@
 import androidx.core.content.getSystemService
 import androidx.work.Constraints
 import androidx.work.ExistingPeriodicWorkPolicy
-import androidx.work.NetworkType
-import androidx.work.OneTimeWorkRequestBuilder
 import androidx.work.PeriodicWorkRequestBuilder
 import androidx.work.WorkManager
-import com.geekorum.ttrss.add_feed.AddFeedWorker
 import com.geekorum.ttrss.providers.ArticlesContract
 import com.geekorum.ttrss.providers.PurgeArticlesWorker
 import com.geekorum.ttrss.sync.SyncContract
@@ -66,13 +63,6 @@
         setupPeriodicPurge()
     }
 
-    fun subscribeToFeed(
-        account: Account, feedUrl: String, categoryId: Long,
-        feedLogin: String, feedPassword: String
-    ) {
-        impl.subscribeToFeed(account, feedUrl, categoryId, feedLogin, feedPassword)
-    }
-
     private fun setupPeriodicPurge() {
         impl.setupPeriodicPurge()
     }
@@ -152,21 +142,5 @@
                 BackgroundJobManager.PERIODIC_PURGE_JOB, ExistingPeriodicWorkPolicy.KEEP, request)
     }
 
-    fun subscribeToFeed(
-        account: Account, feedUrl: String,
-        categoryId: Long, feedLogin: String, feedPassword: String
-    ) {
-        val inputData = AddFeedWorker.getInputData(account, feedUrl, categoryId, feedLogin, feedPassword)
-        val workRequest = OneTimeWorkRequestBuilder<AddFeedWorker>()
-            .setConstraints(Constraints.Builder()
-                .setRequiredNetworkType(NetworkType.CONNECTED)
-                .build())
-            .setInputData(inputData)
-            .build()
-
-        WorkManager.getInstance(context)
-            .enqueue(workRequest)
-    }
-
 }
 
--- a/app/src/main/res/layout/activity_add_feed.xml	Wed Jun 26 17:23:17 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,191 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-
-    Geekttrss is a RSS feed reader application on the Android Platform.
-
-    Copyright (C) 2017-2019 by Frederic-Charles Barthelery.
-
-    This file is part of Geekttrss.
-
-    Geekttrss is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Geekttrss is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Geekttrss.  If not, see <http://www.gnu.org/licenses/>.
-
--->
-<layout xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:tools="http://schemas.android.com/tools"
-        xmlns:app="http://schemas.android.com/apk/res-auto"
-        >
-
-    <data>
-        <import type="android.view.View" />
-        <variable name="viewModel" type="com.geekorum.ttrss.add_feed.AddFeedViewModel" />
-    </data>
-
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content">
-
-        <TextView android:id="@+id/title"
-                  android:layout_width="match_parent"
-                  android:layout_height="96dp"
-                  android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-                  android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-                  app:layout_constraintStart_toStartOf="parent"
-                  app:layout_constraintEnd_toEndOf="parent"
-                  app:layout_constraintTop_toTopOf="parent"
-                  android:layout_marginBottom="16dp"
-                  android:gravity="center_vertical"
-                  android:textAppearance="@style/TextAppearance.AppCompat.Display1"
-                  android:textColor="?android:textColorPrimary"
-                  android:textSize="28sp"
-                  android:text="@string/activity_add_feed_title"
-                  android:background="@color/primary"
-                  android:theme="@style/ThemeOverlay.AppCompat.Dark"
-                />
-
-
-        <Spinner android:id="@+id/available_feeds"
-                 android:layout_width="match_parent"
-                 android:layout_height="?attr/listPreferredItemHeightSmall"
-                 app:layout_constraintStart_toStartOf="parent"
-                 app:layout_constraintEnd_toEndOf="parent"
-                 app:layout_constraintTop_toBottomOf="@+id/title"
-                 android:paddingStart="8dp"
-                 android:paddingEnd="8dp"
-                 android:visibility="@{viewModel.availableFeeds.size() &gt; 1 ? View.VISIBLE : View.INVISIBLE }"
-                 android:onItemSelected="@{(spinner, view, position, id) -> viewModel.setSelectedFeed(spinner.getItemAtPosition(position))}"
-                />
-
-
-        <androidx.core.widget.ContentLoadingProgressBar
-                android:id="@+id/loading_progress"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginStart="?android:listPreferredItemPaddingStart"
-                android:layout_marginEnd="?android:listPreferredItemPaddingStart"
-                android:layout_marginHorizontal="?android:listPreferredItemPaddingStart"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toTopOf="@+id/available_feeds_single"
-                app:layout_constraintBottom_toBottomOf="@+id/available_feeds_single"
-                style="?android:progressBarStyleSmall"
-                tools:ignore="UnusedAttribute" />
-
-
-        <TextView android:id="@+id/available_feeds_single"
-                 android:layout_width="0dp"
-                 android:layout_height="?attr/listPreferredItemHeightSmall"
-                 app:layout_constraintStart_toEndOf="@+id/loading_progress"
-                 app:layout_constraintEnd_toEndOf="parent"
-                 app:layout_constraintTop_toBottomOf="@+id/title"
-                 android:paddingStart="?android:listPreferredItemPaddingStart"
-                 android:paddingEnd="?android:listPreferredItemPaddingStart"
-                 android:textAppearance="?android:attr/textAppearanceLargePopupMenu"
-                 android:gravity="center_vertical"
-                 android:visibility="@{viewModel.availableFeeds.size() &gt; 1 ? View.INVISIBLE : View.VISIBLE }"
-                 android:text="@string/activity_add_feed_looking_for_feed"
-                />
-
-
-
-        <androidx.constraintlayout.widget.Group
-                android:layout_width="wrap_content" android:layout_height="wrap_content"
-                app:constraint_referenced_ids="accounts_panel,accounts_label,available_accounts"
-                android:visibility="@{viewModel.accounts.length &gt; 1 ? View.VISIBLE : View.GONE }"
-                />
-
-
-        <!-- Background of the accounts panel -->
-        <View android:id="@+id/accounts_panel"
-                android:layout_width="match_parent"
-                android:layout_height="0dp"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintTop_toBottomOf="@+id/available_feeds"
-                app:layout_constraintBottom_toTopOf="@id/button_bar"
-                android:layout_marginTop="?listPreferredItemHeightSmall"
-                android:background="@color/background_add_feed_accounts_panel"/>
-
-        <TextView android:id="@+id/accounts_label"
-                  android:layout_width="match_parent"
-                  android:layout_height="24dp"
-                  android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-                  android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-                  app:layout_constraintStart_toStartOf="parent"
-                  app:layout_constraintEnd_toEndOf="parent"
-                  app:layout_constraintTop_toTopOf="@id/accounts_panel"
-                  android:gravity="center_vertical"
-                  android:textAppearance="?textAppearanceCaption"
-                  android:textColor="?android:textColorPrimary"
-                  android:text="@string/activity_add_feed_account_subtitle"
-                />
-
-        <Spinner android:id="@+id/available_accounts"
-                 android:layout_width="match_parent"
-                 android:layout_height="?attr/listPreferredItemHeightSmall"
-                 app:layout_constraintStart_toStartOf="parent"
-                 app:layout_constraintEnd_toEndOf="parent"
-                 app:layout_constraintTop_toBottomOf="@+id/accounts_label"
-                 android:paddingEnd="8dp"
-                 android:paddingStart="8dp"
-                 android:onItemSelected="@{(spinner, view, position, id) -> viewModel.setSelectedAccount(spinner.getItemAtPosition(position))}"
-                 android:theme="@style/ThemeOverlay.AppTheme.AddFeedActivity.AccountsPanel"
-        />
-
-        <LinearLayout
-                android:id="@+id/button_bar"
-                style="?attr/buttonBarStyle"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintTop_toBottomOf="@id/available_accounts"
-                android:gravity="end|center_vertical"
-                android:orientation="horizontal"
-                android:measureWithLargestChild="true"
-                android:paddingTop="8dp"
-                android:paddingBottom="8dp"
-                android:paddingStart="12dp"
-                android:paddingEnd="12dp"
-                android:elevation="8dp">
-
-            <Button
-                    android:id="@+id/cancel"
-                    android:layout_width="wrap_content"
-                    android:layout_gravity="start"
-                    android:maxLines="2"
-                    style="?attr/buttonBarNegativeButtonStyle"
-                    android:minHeight="48dp"
-                    android:layout_height="wrap_content"
-                    android:text="@android:string/cancel"
-                    android:onClick="@{() -> viewModel.cancel()}"
-                    />
-
-            <Button
-                    android:id="@+id/subscribe"
-                    android:layout_width="wrap_content"
-                    android:layout_gravity="end"
-                    android:maxLines="2"
-                    android:minHeight="48dp"
-                    style="?attr/buttonBarPositiveButtonStyle"
-                    android:layout_height="wrap_content"
-                    android:text="@string/activity_add_feed_btn_subscribe"
-                    android:onClick="@{() -> viewModel.subscribeToFeed()}"
-                    android:enabled="@{viewModel.canSubscribe}"
-                    />
-        </LinearLayout>
-
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-</layout>
--- a/app/src/main/res/layout/item_choose_account.xml	Wed Jun 26 17:23:17 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-
-    Geekttrss is a RSS feed reader application on the Android Platform.
-
-    Copyright (C) 2017-2019 by Frederic-Charles Barthelery.
-
-    This file is part of Geekttrss.
-
-    Geekttrss is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Geekttrss is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Geekttrss.  If not, see <http://www.gnu.org/licenses/>.
-
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              xmlns:tools="http://schemas.android.com/tools"
-              tools:context=".add_feed.AddFeedActivity"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              style="?android:attr/spinnerDropDownItemStyle"
-              android:orientation="horizontal">
-
-    <ImageView android:id="@+id/account_row_icon"
-               android:layout_width="36dp"
-               android:layout_height="36dp"
-               android:layout_gravity="center_vertical"
-               android:paddingEnd="8dip"
-               tools:ignore="RtlSymmetry" />
-
-    <TextView android:id="@+id/account_row_text"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              android:textAppearance="?android:attr/textAppearanceListItemSecondary"
-              android:gravity="center_vertical"
-              android:minHeight="?attr/listPreferredItemHeightSmall" />
-
-</LinearLayout>
--- a/app/src/main/res/values-night/colors.xml	Wed Jun 26 17:23:17 2019 -0700
+++ b/app/src/main/res/values-night/colors.xml	Wed Jun 26 17:35:58 2019 -0700
@@ -35,7 +35,4 @@
 
     <color name="image_scrim">#88000000</color>
 
-    <!-- Add feed account panel -->
-    <color name="background_add_feed_accounts_panel">@color/material_blue_grey_900</color>
-    <color name="background_add_feed_accounts_spinner">@color/material_blue_grey_800</color>
 </resources>
--- a/app/src/main/res/values/colors.xml	Wed Jun 26 17:23:17 2019 -0700
+++ b/app/src/main/res/values/colors.xml	Wed Jun 26 17:35:58 2019 -0700
@@ -52,8 +52,4 @@
     <color name="image_scrim">#ccffffff</color>
     <color name="article_text_color">?android:textColorTertiary</color>
 
-    <!-- Add feed account panel -->
-    <color name="background_add_feed_accounts_panel">@color/material_blue_grey_100</color>
-    <color name="background_add_feed_accounts_spinner">@color/material_blue_grey_200</color>
-
 </resources>
--- a/app/src/main/res/values/strings.xml	Wed Jun 26 17:23:17 2019 -0700
+++ b/app/src/main/res/values/strings.xml	Wed Jun 26 17:35:58 2019 -0700
@@ -87,10 +87,6 @@
 
     <!-- activity add feed -->
     <string name="activity_add_feed_title">Subscribe to feed</string>
-    <string name="activity_add_feed_no_feeds_available">No feeds available</string>
-    <string name="activity_add_feed_looking_for_feed">Looking for feed</string>
-    <string name="activity_add_feed_account_subtitle">Account</string>
-    <string name="activity_add_feed_btn_subscribe">Subscribe</string>
 
     <!-- Menus -->
     <string name="share_article">Share article</string>
--- a/app/src/main/res/values/styles.xml	Wed Jun 26 17:23:17 2019 -0700
+++ b/app/src/main/res/values/styles.xml	Wed Jun 26 17:35:58 2019 -0700
@@ -73,28 +73,8 @@
         <item name="android:navigationBarColor">?android:colorBackground</item>
     </style>
 
-    <style name="AppTheme.AddFeedActivity" parent="@style/Theme.MaterialComponents.DayNight.BottomSheetDialog">
-        <!-- use the material Blue Grey palette -->
-        <item name="colorPrimary">@color/primary</item>
-        <item name="colorPrimaryDark">@color/primary_darker</item>
-        <item name="colorPrimaryVariant">@color/primary_variant</item>
-        <item name="colorSecondary">@color/secondary</item>
-        <item name="colorSecondaryVariant">@color/secondary_variant</item>
-        <item name="colorOnPrimary">@color/color_on_primary</item>
-        <item name="colorOnSecondary">@color/color_on_secondary</item>
-
-        <!-- needed for a BottomDialogActivity -->
-        <item name="windowNoTitle">true</item>
-        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
-        <item name="android:windowTranslucentStatus">false</item>
-    </style>
-
     <!-- Theme overlays -->
 
-    <style name="ThemeOverlay.AppTheme.AddFeedActivity.AccountsPanel" parent="ThemeOverlay.AppTheme.DayNight">
-        <item name="android:colorBackground">@color/background_add_feed_accounts_spinner</item>
-    </style>
-
     <style name="ThemeOverlay.AppTheme.TranslucentButton" parent="ThemeOverlay.AppTheme.DayNight">
         <item name="colorButtonNormal">@android:color/transparent</item>
     </style>
@@ -161,5 +141,6 @@
 
     <!-- defined in feature modules -->
     <style name="AppTheme.ManageFeedsActivity" tools:ignore="UnusedResources"/>
+    <style name="AppTheme.AddFeedActivity" tools:ignore="UnusedResources"/>
 
 </resources>
--- a/app/src/test/java/com/geekorum/ttrss/add_feed/AddFeedViewModelTest.kt	Wed Jun 26 17:23:17 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-/*
- * Geekttrss is a RSS feed reader application on the Android Platform.
- *
- * Copyright (C) 2017-2019 by Frederic-Charles Barthelery.
- *
- * This file is part of Geekttrss.
- *
- * Geekttrss is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Geekttrss is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Geekttrss.  If not, see <http://www.gnu.org/licenses/>.
- */
-package com.geekorum.ttrss.add_feed
-
-import android.accounts.Account
-import android.accounts.AccountManager
-import androidx.arch.core.executor.testing.InstantTaskExecutorRule
-import androidx.lifecycle.Observer
-import com.geekorum.geekdroid.app.lifecycle.EventObserver
-import com.geekorum.ttrss.background_job.BackgroundJobManager
-import com.geekorum.ttrss.html.FeedExtractor
-import com.geekorum.ttrss.html.FeedInformation
-import com.google.common.truth.Truth.assertThat
-import io.mockk.Runs
-import io.mockk.coEvery
-import io.mockk.every
-import io.mockk.just
-import io.mockk.mockk
-import io.mockk.verify
-import kotlinx.coroutines.runBlocking
-import okhttp3.HttpUrl
-import okhttp3.OkHttpClient
-import org.junit.Rule
-import java.io.IOException
-import kotlin.test.BeforeTest
-import kotlin.test.Test
-
-
-class AddFeedViewModelTest {
-
-    @get:Rule
-    val archRule = InstantTaskExecutorRule()
-
-
-    private lateinit var target: AddFeedViewModel
-    private lateinit var okHttpClient: OkHttpClient
-    private lateinit var feedExtractor: FeedExtractor
-    private lateinit var backgroundJobManager: BackgroundJobManager
-    private lateinit var accountManager: AccountManager
-
-    @BeforeTest
-    fun setup() {
-        okHttpClient = mockk()
-        feedExtractor = mockk()
-        backgroundJobManager = mockk()
-        accountManager = mockk(relaxed = true)
-        target = AddFeedViewModel(feedExtractor, okHttpClient, backgroundJobManager, accountManager)
-    }
-
-    @Test
-    fun testThatInitDocumentReturnsCorrectFeeds() {
-        val feeds = listOf(
-            FeedInformation(HttpUrl.parse("https://google.com")!!, "type", "title"),
-            FeedInformation(HttpUrl.parse("https://apple.com")!!, "type2", "title2"))
-        every { feedExtractor.extract(any<String>()) }.returns( feeds)
-
-        var result: List<FeedInformation>? = null
-        val observer = Observer<List<FeedInformation>> {
-            result = it
-        }
-        target.availableFeeds.observeForever(observer)
-        target.init("long html document")
-
-        assertThat(result).isEqualTo(feeds)
-    }
-
-    @Test
-    fun testThatInitUrlReturnsCorrectFeeds() {
-        val feeds = listOf(
-            FeedInformation(HttpUrl.parse("https://google.com")!!, "type", "title"),
-            FeedInformation(HttpUrl.parse("https://apple.com")!!, "type2", "title2"))
-        every { feedExtractor.extract(any<String>()) }.returns( feeds)
-        coEvery { okHttpClient.newCall(any()).execute().body()!!.string() } returns("anything")
-        coEvery { okHttpClient.newCall(any()).execute().close() } just Runs
-
-        var result: List<FeedInformation>? = null
-        val observer = Observer<List<FeedInformation>> {
-            result = it
-        }
-        target.availableFeeds.observeForever(observer)
-        runBlocking {
-            target.initWithUrl(HttpUrl.parse("https://some.google.com/")!!)
-        }
-
-        assertThat(result).isEqualTo(feeds)
-    }
-
-
-    @Test
-    fun testThatInitUrlWithExceptionReturnsEmptyFeeds() {
-        coEvery { okHttpClient.newCall(any()).execute() } throws IOException("No network")
-
-        var result: List<FeedInformation>? = null
-        val observer = Observer<List<FeedInformation>> {
-            result = it
-        }
-        target.availableFeeds.observeForever(observer)
-        runBlocking {
-            target.initWithUrl(HttpUrl.parse("https://some.google.com/")!!)
-        }
-
-        assertThat(result).isEmpty()
-    }
-
-    @Test
-    fun testThatSubscribeFeedCallsBackgroundJobManager() {
-        val account: Account = mockk()
-        target.selectedFeed = FeedInformation(HttpUrl.parse("https://google.com/")!!, "type", "title")
-        target.selectedAccount = account
-        every { backgroundJobManager.subscribeToFeed(any(), any(), any(), any(), any()) } just Runs
-
-        target.subscribeToFeed()
-
-        verify { backgroundJobManager.subscribeToFeed(any(), "https://google.com/", any(), any(), any()) }
-    }
-
-    @Test
-    fun testThatCanSubscribeOnceSelectionIsDone() {
-        assertThat(target.canSubscribe.get()).isFalse()
-
-        target.selectedAccount = mockk()
-        target.selectedFeed = mockk()
-
-        assertThat(target.canSubscribe.get()).isTrue()
-    }
-
-
-    @Test
-    fun testThatSubscribeEmitCompleteEvent() {
-        target.selectedFeed = FeedInformation(HttpUrl.parse("https://google.com/")!!, "type", "title")
-        target.selectedAccount = mockk()
-        every { backgroundJobManager.subscribeToFeed(any(), any(), any(), any(), any()) } just Runs
-
-        var called = false
-        val observer = EventObserver<Any> {
-            called = true
-        }
-        target.complete.observeForever(observer)
-        target.subscribeToFeed()
-
-        assertThat(called).isTrue()
-    }
-
-    @Test
-    fun testThatCanelEmitCompleteEvent() {
-        var called = false
-        val observer = EventObserver<Any> {
-            called = true
-        }
-        target.complete.observeForever(observer)
-        target.cancel()
-
-        assertThat(called).isTrue()
-    }
-}