-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement removeProduct method of ProductStore
- Loading branch information
1 parent
9d2ae15
commit d341fb1
Showing
7 changed files
with
229 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package ru.ekuzmichev | ||
|
||
import org.telegram.telegrambots.client.okhttp.OkHttpTelegramClient | ||
import org.telegram.telegrambots.longpolling.TelegramBotsLongPollingApplication | ||
import org.telegram.telegrambots.longpolling.util.LongPollingSingleThreadUpdateConsumer | ||
import org.telegram.telegrambots.meta.api.methods.send.SendMessage | ||
import org.telegram.telegrambots.meta.api.objects.Update | ||
import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup | ||
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.{InlineKeyboardButton, InlineKeyboardRow} | ||
import org.telegram.telegrambots.meta.generics.TelegramClient | ||
|
||
object KeyboardBotTestApp extends App: | ||
val botToken = "7214794484:AAEmry5Wwg-uW-bCa4QbK6dUZFzM5VdRbL4" | ||
|
||
val botsApplication = new TelegramBotsLongPollingApplication() | ||
botsApplication.registerBot(botToken, new KeyboardTestingBot(new OkHttpTelegramClient(botToken))) | ||
|
||
println("MyAmazingBot successfully started!") | ||
|
||
class KeyboardTestingBot(telegramClient: TelegramClient) extends LongPollingSingleThreadUpdateConsumer: | ||
override def consume(update: Update): Unit = | ||
println { update } | ||
if update.getMessage != null then | ||
val messageText = "Fuck!" | ||
val chatId = update.getMessage.getChatId | ||
|
||
val inlineKeyboardButtons: Seq[InlineKeyboardButton] = (1 to 1).map(index => | ||
InlineKeyboardButton | ||
.builder() | ||
.text(s"$index umnyy-robot-pylesos-red-solution-rv-rl6000s-wi-fi-suhaya-i-vlazhnaya-uborka-879677278") | ||
.callbackData(index.toString) | ||
.build() | ||
) | ||
|
||
val inlineKeyboardRow: InlineKeyboardRow = new InlineKeyboardRow( | ||
inlineKeyboardButtons* | ||
) | ||
|
||
val inlineKeyboardMarkup: InlineKeyboardMarkup = InlineKeyboardMarkup | ||
.builder() | ||
.keyboardRow(inlineKeyboardRow) | ||
.keyboardRow(inlineKeyboardRow) | ||
.keyboardRow(inlineKeyboardRow) | ||
.keyboardRow(inlineKeyboardRow) | ||
.keyboardRow(inlineKeyboardRow) | ||
.keyboardRow(inlineKeyboardRow) | ||
.keyboardRow(inlineKeyboardRow) | ||
.keyboardRow(new InlineKeyboardRow( | ||
InlineKeyboardButton | ||
.builder() | ||
.text("More") | ||
.callbackData("more") | ||
.build() | ||
)) | ||
.build() | ||
|
||
val message: SendMessage = SendMessage | ||
.builder() | ||
.text("Hello you!") | ||
.chatId(chatId) | ||
.replyMarkup(inlineKeyboardMarkup) | ||
.build() | ||
|
||
telegramClient.execute(message) | ||
else if update.getCallbackQuery != null then | ||
println { | ||
update.getCallbackQuery.getMessage.getChatId | ||
} | ||
println { | ||
update.getCallbackQuery.getId | ||
} | ||
println { | ||
update.getCallbackQuery.getData | ||
} | ||
println { | ||
update.getCallbackQuery.getFrom | ||
} | ||
|
||
val message: SendMessage = SendMessage | ||
.builder() | ||
.text(update.getCallbackQuery.getData) | ||
.chatId(update.getCallbackQuery.getMessage.getChatId) | ||
.build() | ||
|
||
telegramClient.execute(message) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package ru.ekuzmichev | ||
package store | ||
|
||
import common.ProductId | ||
import store.InMemoryProductStore.ProductState | ||
import store.ProductStore.{Product, SourceId, SourceState} | ||
|
||
import zio.test.* | ||
import zio.test.Assertion.* | ||
import zio.{Ref, Scope, UIO} | ||
|
||
object InMemoryProductStoreTest extends ZIOSpecDefault: | ||
override def spec: Spec[TestEnvironment with Scope, Any] = | ||
suite("InMemoryProductStore")( | ||
test("preInitialize should fill state with initial data") { | ||
import Fixtures.sourceStatesBySortId | ||
for | ||
productStore <- makeProductStore() | ||
stateBeforeInitialization <- productStore.readAll() | ||
_ <- productStore.preInitialize(sourceStatesBySortId) | ||
stateAfterInitialization <- productStore.readAll() | ||
yield assertTrue(stateBeforeInitialization.isEmpty) && | ||
assert(stateAfterInitialization)(hasSameElements(sourceStatesBySortId)) | ||
}, | ||
test("checkInitialized should return true if sourceId exists and false otherwise") { | ||
import Fixtures.{bobSourceId, fritzSourceId, pamelaSourceId} | ||
for | ||
productStore <- makePreInitializedProductStore() | ||
bobInitialized <- productStore.checkInitialized(bobSourceId) | ||
fritzInitialized <- productStore.checkInitialized(fritzSourceId) | ||
pamelaInitialized <- productStore.checkInitialized(pamelaSourceId) | ||
yield assertTrue(bobInitialized, fritzInitialized, !pamelaInitialized) | ||
}, | ||
test("emptyState should remove all products for sourceId") { | ||
import Fixtures.bobSourceId | ||
for | ||
productStore <- makePreInitializedProductStore() | ||
_ <- productStore.emptyState(bobSourceId) | ||
stateAfterEmptiness <- productStore.readAll() | ||
yield assertTrue(stateAfterEmptiness(bobSourceId).products.isEmpty) | ||
}, | ||
test("clearState should remove whole state for sourceId") { | ||
import Fixtures.bobSourceId | ||
for | ||
productStore <- makePreInitializedProductStore() | ||
_ <- productStore.clearState(bobSourceId) | ||
stateAfterClearance <- productStore.readAll() | ||
yield assertTrue(!stateAfterClearance.contains(bobSourceId)) | ||
}, | ||
test("readSourceState should read state for sourceId") { | ||
import Fixtures.{bobSourceId, bobSourceState} | ||
for | ||
productStore <- makePreInitializedProductStore() | ||
readBobSourceState <- productStore.readSourceState(bobSourceId) | ||
yield assertTrue(readBobSourceState.get == bobSourceState) | ||
}, | ||
test("addProduct should add product to product list of sourceId if sourceId exists") { | ||
import Fixtures.{bobSourceId, pamelaSourceId} | ||
for | ||
productStore <- makePreInitializedProductStore() | ||
newProduct = Product("blue-water", 1500) | ||
bobProductAdded <- productStore.addProduct(bobSourceId, newProduct) | ||
readBobSourceState <- productStore.readSourceState(bobSourceId) | ||
pamelaProductAdded <- productStore.addProduct(pamelaSourceId, newProduct) | ||
yield assertTrue(bobProductAdded, readBobSourceState.get.products.contains(newProduct), !pamelaProductAdded) | ||
}, | ||
test("checkHasProductId should return true if product with id exists and false otherwise") { | ||
import Fixtures.{bobSourceId, redKettleProductId, whiteLampProductId} | ||
for | ||
productStore <- makePreInitializedProductStore() | ||
hasRedKettleProduct <- productStore.checkHasProductId(bobSourceId, redKettleProductId) | ||
hasWhiteLampProduct <- productStore.checkHasProductId(bobSourceId, whiteLampProductId) | ||
yield assertTrue(hasRedKettleProduct, !hasWhiteLampProduct) | ||
}, | ||
test("removeProduct should remove product from product list of sourceId if sourceId exists") { | ||
import Fixtures.{bobSourceId, pamelaSourceId, redKettleProductId} | ||
for | ||
productStore <- makePreInitializedProductStore() | ||
bobProductRemoved <- productStore.removeProduct(bobSourceId, redKettleProductId) | ||
readBobSourceState <- productStore.readSourceState(bobSourceId) | ||
pamelaProductRemoved <- productStore.removeProduct(pamelaSourceId, redKettleProductId) | ||
yield assertTrue( | ||
bobProductRemoved, | ||
!readBobSourceState.get.products.exists(_.id == redKettleProductId), | ||
!pamelaProductRemoved | ||
) | ||
} | ||
) | ||
|
||
private def makePreInitializedProductStore(): UIO[InMemoryProductStore] = | ||
import Fixtures.sourceStatesBySortId | ||
makeProductStore().tap(_.preInitialize(sourceStatesBySortId).ignore) | ||
|
||
private def makeProductStore(): UIO[InMemoryProductStore] = | ||
for productStateRef <- Ref.make(ProductState.empty) | ||
yield new InMemoryProductStore(productStateRef) | ||
|
||
private object Fixtures: | ||
val bobSourceId: SourceId = SourceId("bob", "123") | ||
val fritzSourceId: SourceId = SourceId("fritz", "456") | ||
val pamelaSourceId: SourceId = SourceId("pamela", "789") | ||
|
||
val redKettleProductId: ProductId = "red-kettle" | ||
val brownPenProductId: ProductId = "brown-pen" | ||
val yellowPillowProductId: ProductId = "yellow-pillow" | ||
val darkToyProductId: ProductId = "dark-toy" | ||
val greenGrassProductId: ProductId = "green-grass" | ||
val whiteLampProductId: ProductId = "white-lamp" | ||
|
||
val bobSourceState: SourceState = SourceState( | ||
products = Seq( | ||
Product(redKettleProductId, 1000), | ||
Product(brownPenProductId, 300) | ||
), | ||
maybeProductCandidate = None | ||
) | ||
|
||
val fritzSourceState: SourceState = SourceState( | ||
products = Seq( | ||
Product(yellowPillowProductId, 2000), | ||
Product(darkToyProductId, 300), | ||
Product(greenGrassProductId, 100) | ||
), | ||
maybeProductCandidate = None | ||
) | ||
|
||
val sourceStatesBySortId: Map[SourceId, SourceState] = Map( | ||
bobSourceId -> bobSourceState, | ||
fritzSourceId -> fritzSourceState | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters