Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/commands/domains/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {Command, flags} from '@heroku-cli/command'
import * as Heroku from '@heroku-cli/schema'
import {color, hux} from '@heroku/heroku-cli-util'
import {HerokuSDK} from '@heroku/sdk'
import {ux} from '@oclif/core/ux'
import {orderBy} from 'natural-orderby'
import Uri from 'urijs'

import parseKeyValue from '../../lib/utils/key-value-parser.js'
import {paginateRequest} from '../../lib/utils/paginator.js'
import {huxTableNoWrapOptions} from '../../lib/utils/table-utils.js'

export default class DomainsIndex extends Command {
Expand Down Expand Up @@ -175,7 +175,8 @@ www.example.com CNAME www.example.herokudns.com`]

async run() {
const {flags} = await this.parse(DomainsIndex)
const domains = await paginateRequest<Heroku.Domain>(this.heroku, `/apps/${flags.app}/domains`, 1000)
const {platform} = new HerokuSDK()
const domains = await platform.domain.list(flags.app) as Heroku.Domain[]
const herokuDomain = domains.find((domain: Heroku.Domain) => domain.kind === 'heroku')
let customDomains = domains.filter((domain: Heroku.Domain) => domain.kind === 'custom')
let displayTotalDomains = false
Expand Down
6 changes: 4 additions & 2 deletions src/commands/features/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {Command, flags} from '@heroku-cli/command'
import * as Heroku from '@heroku-cli/schema'
import type {AppFeature} from '@heroku/types/3.sdk'
import {color, hux} from '@heroku/heroku-cli-util'
import {HerokuSDK} from '@heroku/sdk'
import {ux} from '@oclif/core/ux'

export default class Features extends Command {
Expand All @@ -15,7 +16,8 @@ export default class Features extends Command {
const {flags} = await this.parse(Features)
const {app, json} = flags

let {body: features} = await this.heroku.get<Heroku.AppFeature[]>(`/apps/${app}/features`)
const {platform} = new HerokuSDK()
let features = await platform.appFeature.list(app) as AppFeature[]
features = features.filter(f => f.state === 'general')
features = features.sort((a, b) => (a.name || '').localeCompare(b.name || ''))

Expand Down
10 changes: 5 additions & 5 deletions src/commands/spaces/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Command, flags as Flags} from '@heroku-cli/command'
import {color, hux} from '@heroku/heroku-cli-util'
import {HerokuSDK} from '@heroku/sdk'
import {ux} from '@oclif/core/ux'

import {getGeneration} from '../../lib/apps/generation.js'
Expand Down Expand Up @@ -47,11 +48,10 @@ export default class Index extends Command {
public async run(): Promise<void> {
const {flags} = await this.parse(Index)
const {json, team} = flags
let {body: spaces} = await this.heroku.get<SpaceArray>('/spaces', {
headers: {
Accept: 'application/vnd.heroku+json; version=3.sdk',
},
})
const {platform} = new HerokuSDK()
let spaces = await platform
.withHeaders({Accept: 'application/vnd.heroku+json; version=3.sdk'})
.space.list() as SpaceArray
if (team) {
spaces = spaces.filter(s => s.team.name === team)
}
Expand Down
32 changes: 0 additions & 32 deletions src/lib/utils/paginator.ts

This file was deleted.

67 changes: 38 additions & 29 deletions test/unit/commands/domains/index.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,37 @@
import {runCommand} from '@heroku-cli/test-utils'
import {hux} from '@heroku/heroku-cli-util'
import {HerokuSDK} from '@heroku/sdk'
import {expect} from 'chai'
import nock from 'nock'
import * as sinon from 'sinon'
import {SinonStub, stub} from 'sinon'

import DomainsIndex from '../../../../src/commands/domains/index.js'
import removeAllWhitespace from '../../../helpers/utils/remove-whitespaces.js'
import {unwrap} from '../../../helpers/utils/unwrap.js'

type FakePlatform = {
domain: {list: sinon.SinonStub}
}

function buildFakePlatform(): FakePlatform {
return {
domain: {list: sinon.stub()},
}
}

describe('domains', function () {
let confirmStub: SinonStub
let api: nock.Scope
let fakePlatform: FakePlatform

beforeEach(function () {
api = nock('https://api.heroku.com')
fakePlatform = buildFakePlatform()
sinon.stub(HerokuSDK.prototype, 'platform').get(() => fakePlatform)
confirmStub = stub(DomainsIndex.prototype, 'confirmDisplayAllDomains')
.resolves(true)
})

afterEach(function () {
api.done()
confirmStub.restore()
nock.cleanAll()
sinon.restore()
})

const herokuOnlyDomainsResponse = [
Expand Down Expand Up @@ -114,16 +124,17 @@ describe('domains', function () {
]

it('does not show the custom domain header if there are no custom domains', async function () {
api.get('/apps/myapp/domains').reply(200, herokuOnlyDomainsResponse)
fakePlatform.domain.list.resolves(herokuOnlyDomainsResponse)

const {stdout} = await runCommand(DomainsIndex, ['--app', 'myapp'])
expect(stdout).to.contain('=== ⬢ myapp Heroku Domain\n\nmyapp.herokuapp.com')
expect(stdout).to.contain('myapp.herokuapp.com')
expect(stdout).to.not.contain('=== ⬢ myapp Custom Domains')
expect(fakePlatform.domain.list.calledOnceWithExactly('myapp')).to.equal(true)
})

it('shows a list of domains and their DNS targets when there are custom domains', async function () {
api.get('/apps/myapp/domains').reply(200, herokuAndCustomDomainsResponse)
fakePlatform.domain.list.resolves(herokuAndCustomDomainsResponse)

const {stdout} = await runCommand(DomainsIndex, ['--app', 'myapp'])
const actual = removeAllWhitespace(stdout)
Expand All @@ -137,7 +148,7 @@ describe('domains', function () {
})

it('shows the SNI endpoint column when multiple sni endpoints are enabled', async function () {
api.get('/apps/myapp/domains').reply(200, herokuDomainWithSniEndpoint)
fakePlatform.domain.list.resolves(herokuDomainWithSniEndpoint)

const {stdout} = await runCommand(DomainsIndex, ['--app', 'myapp'])
const actual = removeAllWhitespace(stdout)
Expand All @@ -146,33 +157,31 @@ describe('domains', function () {
})

it('shows warning message for over 100 domains', async function () {
api.get('/apps/myapp/domains').reply(200, () => {
const domainData = {
acm_status: null,
acm_status_reason: null,
app: {
id: '01234567-89ab-cdef-0123-456789abcdef',
name: 'myapp',
},
cname: null,
created_at: '2012-01-01T12:00:00Z',
hostname: 'example.com',
id: '11434567-89ab-cdef-0123-456789abcdef',
kind: 'custom',
status: 'succeeded',
updated_at: '2012-01-01T12:00:00Z',
}

return new Array(1000).fill(domainData) // eslint-disable-line unicorn/no-new-array
})
const domainData = {
acm_status: null,
acm_status_reason: null,
app: {
id: '01234567-89ab-cdef-0123-456789abcdef',
name: 'myapp',
},
cname: null,
created_at: '2012-01-01T12:00:00Z',
hostname: 'example.com',
id: '11434567-89ab-cdef-0123-456789abcdef',
kind: 'custom',
status: 'succeeded',
updated_at: '2012-01-01T12:00:00Z',
}

fakePlatform.domain.list.resolves(new Array(1000).fill(domainData)) // eslint-disable-line unicorn/no-new-array

const {stderr, stdout} = await runCommand(DomainsIndex, ['--app', 'myapp'])
expect(stdout).to.contain('=== ⬢ myapp Heroku Domain')
expect(unwrap(stderr)).to.contain('Warning: This app has over 100 domains. Your terminal may not be configured to display the total amount of domains.')
})

it('passes no-wrap option through to table rendering', async function () {
api.get('/apps/myapp/domains').reply(200, herokuAndCustomDomainsResponse)
fakePlatform.domain.list.resolves(herokuAndCustomDomainsResponse)
const tableStub = stub(hux, 'table')

await runCommand(DomainsIndex, ['--app', 'myapp', '--no-wrap'])
Expand Down
78 changes: 63 additions & 15 deletions test/unit/commands/features/index.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,41 @@
import {runCommand} from '@heroku-cli/test-utils'
import {HerokuSDK} from '@heroku/sdk'
import {expect} from 'chai'
import nock from 'nock'
import * as sinon from 'sinon'

import Features from '../../../../src/commands/features/index.js'

type FakePlatform = {
appFeature: {list: sinon.SinonStub}
}

function buildFakePlatform(): FakePlatform {
return {
appFeature: {list: sinon.stub()},
}
}

describe('features', function () {
let api: nock.Scope
let fakePlatform: FakePlatform

beforeEach(function () {
api = nock('https://api.heroku.com')
fakePlatform = buildFakePlatform()
sinon.stub(HerokuSDK.prototype, 'platform').get(() => fakePlatform)
})

afterEach(function () {
api.done()
nock.cleanAll()
sinon.restore()
})

it('shows the app features', async function () {
api
.get('/apps/myapp/features')
.reply(200, [
{
description: 'an app feature',
enabled: true,
name: 'feature a',
state: 'general',
},
])
fakePlatform.appFeature.list.resolves([
{
description: 'an app feature',
enabled: true,
name: 'feature a',
state: 'general',
},
])

const {stderr, stdout} = await runCommand(Features, ['--app', 'myapp'])

Expand All @@ -35,5 +44,44 @@ describe('features', function () {

[+] feature a an app feature
`)
expect(fakePlatform.appFeature.list.calledOnceWithExactly('myapp')).to.equal(true)
})

it('filters out non-general features', async function () {
fakePlatform.appFeature.list.resolves([
{
description: 'a general feature',
enabled: true,
name: 'feature a',
state: 'general',
},
{
description: 'a beta feature',
enabled: false,
name: 'feature b',
state: 'beta',
},
])

const {stdout} = await runCommand(Features, ['--app', 'myapp'])

expect(stdout).to.contain('feature a')
expect(stdout).to.not.contain('feature b')
})

it('shows features as json', async function () {
const features = [
{
description: 'an app feature',
enabled: true,
name: 'feature a',
state: 'general',
},
]
fakePlatform.appFeature.list.resolves(features)

const {stdout} = await runCommand(Features, ['--app', 'myapp', '--json'])

expect(JSON.parse(stdout)).to.deep.equal(features)
})
})
Loading
Loading