@sprucelabs/spruce-cli
Version:
Command line interface for building Spruce skills.
223 lines (178 loc) • 6.63 kB
Plain Text
import {
activeRecordCardAssert,
buttonAssert,
interactor,
MockActiveRecordCard,
vcAssert,
} from '@sprucelabs/heartwood-view-controllers'
import { eventFaker, fake } from '@sprucelabs/spruce-test-fixtures'
import { test, suite, generateId, assert } from '@sprucelabs/test-utils'
import { PublicHomeIntegration } from '../../google.types'
import RootSkillViewController from '../../skillViewControllers/Root.svc'
import AddHomeIntegrationCardViewController from '../../viewControllers/AddHomeIntegrationCard.vc'
import AbstractGoogleTest from '../support/AbstractGoogleTest'
import { DeleteHomeIntergrationTargetAndPayload } from '../support/EventFaker'
import SpyAddHomeIntegrationCard from './homeIntegrations/SpyAddHomeIntegrationCard'
.login()
export default class RootSkillViewTest extends AbstractGoogleTest {
private vc!: SpyRootSkillView
private fakedIntegrations: PublicHomeIntegration[] = []
protected names: string[] = []
protected async beforeEach() {
await super.beforeEach()
this.fakedIntegrations = []
this.names = []
this.views.setController(
'google.add-home-integration-card',
SpyAddHomeIntegrationCard
)
this.views.setController('active-record-card', MockActiveRecordCard)
this.views.setController('google.root', SpyRootSkillView)
this.vc = this.views.Controller('google.root', {}) as SpyRootSkillView
await this.eventFaker.fakeListHomeIntegrations(() => {
return this.fakedIntegrations
})
await this.eventFaker.fakeDeleteHomeIntegration()
}
protected async rendersACard() {
vcAssert.assertSkillViewRendersCard(this.vc, 'home-cloud-integrations')
}
protected async cardRendersList() {
activeRecordCardAssert.skillViewRendersActiveRecordCard(this.vc)
}
protected async requiresLogin() {
await vcAssert.assertLoginIsRequired(this.vc)
}
protected async returnsAListOfIntegrations() {
const integration = this.seedIntegration()
await this.load()
this.assertRendersIntegrationRow(integration.id)
}
protected async homeIntegrationsCardRendersExpectedButtons() {
buttonAssert.cardRendersButtons(this.homeIntegrationsCardVc, [
'instructions',
'add',
])
}
protected async clickingAddIntegrationRendersDialog() {
await this.loadClickAddAndAssertRendersDialog()
}
protected async callingOnDoneInAddCardHidesDialog() {
const { addCardVc, dialogVc } =
await this.loadClickAddAndAssertRendersDialog()
await addCardVc.simulateClickDone()
assert.isFalse(dialogVc.getIsVisible())
}
protected async eachRowRendersDeleteButton() {
const integration = await this.seedOneIntegrationAndLoad()
this.homeIntegrationsCardVc.assertRowRendersButton(
integration.id,
'delete'
)
}
protected async clickingDeleteButtonRendersAlert() {
await this.seedLoadClickDeleteAndAssertConfirm()
}
protected async clickingDeleteAndConfirmingRemovesRow() {
const integration = await this.seedLoadClickDeleteAndConfirm()
this.homeIntegrationsCardVc.assertDoesNotRenderRow(integration.id)
}
protected async doesNotRefreshListIfUserCancels() {
const int = await this.seedLoadClickDeleteAndDecline()
this.assertRendersIntegrationRow(int.id)
}
protected async confirmingDeleteShouldEmitDeleteEvent() {
let passedTarget:
| DeleteHomeIntergrationTargetAndPayload['target']
| undefined
await this.eventFaker.fakeDeleteHomeIntegration(({ target }) => {
passedTarget = target
})
const integration = await this.seedLoadClickDeleteAndConfirm()
assert.isEqualDeep(passedTarget, {
integrationId: integration.id,
})
}
protected async doesNotEmitEventIfDeclined() {
await eventFaker.makeEventThrow(
'google.delete-home-integration::v2025_02_08'
)
await this.seedLoadClickDeleteAndDecline()
}
private async loadClickAddAndAssertRendersDialog() {
await this.load()
const dialogVc = await vcAssert.assertRendersDialog(this.vc, () =>
interactor.clickButton(this.homeIntegrationsCardVc, 'add')
)
const addCardVc = vcAssert.assertRendersAsInstanceOf(
dialogVc,
AddHomeIntegrationCardViewController
) as SpyAddHomeIntegrationCard
return { dialogVc, addCardVc }
}
private async seedLoadClickDeleteAndConfirm() {
const { confirmVc, integration } =
await this.seedLoadClickDeleteAndAssertConfirm()
await confirmVc.accept()
return integration
}
private async seedLoadClickDeleteAndDecline() {
const { confirmVc, integration } =
await this.seedLoadClickDeleteAndAssertConfirm()
const int = integration
await confirmVc.decline()
return int
}
private assertRendersIntegrationRow(id: string) {
this.homeIntegrationsCardVc.assertRendersRow(id)
}
private async seedLoadClickDeleteAndAssertConfirm() {
const integration = await this.seedOneIntegrationAndLoad()
const confirmVc = await vcAssert.assertRendersConfirm(this.vc, () =>
interactor.clickButtonInRow(this.listVc, integration.id, 'delete')
)
return { confirmVc, integration }
}
private get listVc() {
return this.homeIntegrationsCardVc.getListVc()
}
private async seedOneIntegrationAndLoad() {
const integration = this.seedIntegration()
await this.load()
return integration
}
private seedIntegration() {
const integration: PublicHomeIntegration = {
description: generateId(),
id: generateId(),
name: generateId(),
}
this.fakedIntegrations.push(integration)
return integration
}
private async load() {
await this.views.load(this.vc)
}
private get homeIntegrationsCardVc() {
return this.vc.getHomeIntegrationsCardVc()
}
}
class SpyRootSkillView extends RootSkillViewController {
public getHomeIntegrationsCardVc() {
return this.activeRecordCardVc as MockActiveRecordCard
}
}