Lens app source code (#119)

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
Jari Kolehmainen authored and GitHub committed 2020-03-15 09:52:02 +02:00
1 parent 936cbd53d4
commit 1d0815abd2
797 files changed
+73714 -215

No files matched your search

+344
View File
@@ -0,0 +1,344 @@
import * as mockFs from "mock-fs"
import * as yaml from "js-yaml"
jest.mock("electron", () => {
return {
app: {
getVersion: () => '99.99.99',
getPath: () => 'tmp',
getLocale: () => 'en'
}
}
})
// Console.log needs to be called before fs-mocks, see https://github.com/tschaub/mock-fs/issues/234
console.log("");
import { ClusterStore } from "../../../src/common/cluster-store"
import { Cluster } from "../../../src/main/cluster"
describe("for an empty config", () => {
beforeEach(() => {
ClusterStore.resetInstance()
const mockOpts = {
'tmp': {
'lens-cluster-store.json': JSON.stringify({})
}
}
mockFs(mockOpts)
})
afterEach(() => {
mockFs.restore()
})
it("allows to store and retrieve a cluster", async () => {
const cluster = new Cluster({
id: 'foo',
kubeConfig: 'kubeconfig string',
preferences: {
terminalCWD: '/tmp',
icon: 'path to icon'
}
})
const clusterStore = ClusterStore.getInstance()
clusterStore.storeCluster(cluster);
const storedCluster = clusterStore.getCluster(cluster.id);
expect(storedCluster.kubeConfig).toBe(cluster.kubeConfig)
expect(storedCluster.preferences.icon).toBe(cluster.preferences.icon)
expect(storedCluster.preferences.terminalCWD).toBe(cluster.preferences.terminalCWD)
expect(storedCluster.id).toBe(cluster.id)
})
it("allows to delete a cluster", async () => {
const cluster = new Cluster({
id: 'foofoo',
kubeConfig: 'kubeconfig string',
preferences: {
terminalCWD: '/tmp'
}
})
const clusterStore = ClusterStore.getInstance()
clusterStore.storeCluster(cluster);
const storedCluster = clusterStore.getCluster(cluster.id);
expect(storedCluster.id).toBe(cluster.id)
clusterStore.removeCluster(cluster.id);
expect(clusterStore.getCluster(cluster.id)).toBe(null)
})
})
describe("for a config with existing clusters", () => {
beforeEach(() => {
ClusterStore.resetInstance()
const mockOpts = {
'tmp': {
'lens-cluster-store.json': JSON.stringify({
__internal__: {
migrations: {
version: "99.99.99"
}
},
clusters: [
{
id: 'cluster1',
kubeConfig: 'foo',
preferences: { terminalCWD: '/foo' }
},
{
id: 'cluster2',
kubeConfig: 'foo2',
preferences: { terminalCWD: '/foo2' }
}
]
})
}
}
mockFs(mockOpts)
})
afterEach(() => {
mockFs.restore()
})
it("allows to retrieve a cluster", async () => {
const clusterStore = ClusterStore.getInstance()
const storedCluster = clusterStore.getCluster('cluster1')
expect(storedCluster.kubeConfig).toBe('foo')
expect(storedCluster.preferences.terminalCWD).toBe('/foo')
expect(storedCluster.id).toBe('cluster1')
const storedCluster2 = clusterStore.getCluster('cluster2')
expect(storedCluster2.kubeConfig).toBe('foo2')
expect(storedCluster2.preferences.terminalCWD).toBe('/foo2')
expect(storedCluster2.id).toBe('cluster2')
})
it("allows to delete a cluster", async () => {
const clusterStore = ClusterStore.getInstance()
clusterStore.removeCluster('cluster2')
// Verify the other cluster still exists:
const storedCluster = clusterStore.getCluster('cluster1')
expect(storedCluster.id).toBe('cluster1')
const storedCluster2 = clusterStore.getCluster('cluster2')
expect(storedCluster2).toBe(null)
})
it("allows to reload a cluster in-place", async () => {
const cluster = new Cluster({
id: 'cluster1',
kubeConfig: 'kubeconfig string',
preferences: {
terminalCWD: '/tmp'
}
})
const clusterStore = ClusterStore.getInstance()
clusterStore.reloadCluster(cluster)
expect(cluster.kubeConfig).toBe('foo')
expect(cluster.preferences.terminalCWD).toBe('/foo')
expect(cluster.id).toBe('cluster1')
})
it("allows getting all the clusters", async () => {
const clusterStore = ClusterStore.getInstance()
const storedClusters = clusterStore.getAllClusters()
expect(storedClusters[0].id).toBe('cluster1')
expect(storedClusters[0].preferences.terminalCWD).toBe('/foo')
expect(storedClusters[0].kubeConfig).toBe('foo')
expect(storedClusters[1].id).toBe('cluster2')
expect(storedClusters[1].preferences.terminalCWD).toBe('/foo2')
expect(storedClusters[1].kubeConfig).toBe('foo2')
})
it("allows storing the clusters in a different order", async () => {
const clusterStore = ClusterStore.getInstance()
const storedClusters = clusterStore.getAllClusters()
const reorderedClusters = [storedClusters[1], storedClusters[0]]
clusterStore.storeClusters(reorderedClusters)
const storedClusters2 = clusterStore.getAllClusters()
expect(storedClusters2[0].id).toBe('cluster2')
expect(storedClusters2[1].id).toBe('cluster1')
})
})
describe("for a pre 2.0 config with an existing cluster", () => {
beforeEach(() => {
ClusterStore.resetInstance()
const mockOpts = {
'tmp': {
'lens-cluster-store.json': JSON.stringify({
__internal__: {
migrations: {
version: "1.0.0"
}
},
cluster1: 'kubeconfig content'
})
}
}
mockFs(mockOpts)
})
afterEach(() => {
mockFs.restore()
})
it("migrates to modern format with kubeconfig under a key", async () => {
const clusterStore = ClusterStore.getInstance()
const storedCluster = clusterStore.store.get('clusters')[0]
expect(storedCluster.kubeConfig).toBe('kubeconfig content')
})
})
describe("for a pre 2.4.1 config with an existing cluster", () => {
beforeEach(() => {
ClusterStore.resetInstance()
const mockOpts = {
'tmp': {
'lens-cluster-store.json': JSON.stringify({
__internal__: {
migrations: {
version: "2.0.0-beta.2"
}
},
cluster1: {
kubeConfig: 'foo',
online: true,
accessible: false,
failureReason: 'user error'
},
})
}
}
mockFs(mockOpts)
})
afterEach(() => {
mockFs.restore()
})
it("migrates to modern format throwing out the state related data", async () => {
const clusterStore = ClusterStore.getInstance()
const storedClusterData = clusterStore.store.get('clusters')[0]
expect(storedClusterData.hasOwnProperty('online')).toBe(false)
expect(storedClusterData.hasOwnProperty('accessible')).toBe(false)
expect(storedClusterData.hasOwnProperty('failureReason')).toBe(false)
})
})
describe("for a pre 2.6.0 config with a cluster that has arrays in auth config", () => {
beforeEach(() => {
ClusterStore.resetInstance()
const mockOpts = {
'tmp': {
'lens-cluster-store.json': JSON.stringify({
__internal__: {
migrations: {
version: "2.4.1"
}
},
cluster1: {
kubeConfig: "apiVersion: v1\nclusters:\n- cluster:\n server: https://10.211.55.6:8443\n name: minikube\ncontexts:\n- context:\n cluster: minikube\n user: minikube\n name: minikube\ncurrent-context: minikube\nkind: Config\npreferences: {}\nusers:\n- name: minikube\n user:\n client-certificate: /Users/kimmo/.minikube/client.crt\n client-key: /Users/kimmo/.minikube/client.key\n auth-provider:\n config:\n access-token:\n - should be string\n expiry:\n - should be string\n"
},
})
}
}
mockFs(mockOpts)
})
afterEach(() => {
mockFs.restore()
})
it("replaces array format access token and expiry into string", async () => {
const clusterStore = ClusterStore.getInstance()
const storedClusterData = clusterStore.store.get('clusters')[0]
const kc = yaml.safeLoad(storedClusterData.kubeConfig)
expect(kc.users[0].user['auth-provider'].config['access-token']).toBe("should be string")
expect(kc.users[0].user['auth-provider'].config['expiry']).toBe("should be string")
})
})
describe("for a pre 2.6.0 config with a cluster icon", () => {
beforeEach(() => {
ClusterStore.resetInstance()
const mockOpts = {
'tmp': {
'lens-cluster-store.json': JSON.stringify({
__internal__: {
migrations: {
version: "2.4.1"
}
},
cluster1: {
kubeConfig: "foo",
icon: "icon path",
preferences: {
terminalCWD: "/tmp"
}
},
})
}
}
mockFs(mockOpts)
})
afterEach(() => {
mockFs.restore()
})
it("moves the icon into preferences", async () => {
const clusterStore = ClusterStore.getInstance()
const storedClusterData = clusterStore.store.get('clusters')[0]
expect(storedClusterData.hasOwnProperty('icon')).toBe(false)
expect(storedClusterData.preferences.hasOwnProperty('icon')).toBe(true)
expect(storedClusterData.preferences.icon).toBe("icon path")
})
})
describe("for a pre 2.7.0-beta.0 config without a workspace", () => {
beforeEach(() => {
ClusterStore.resetInstance()
const mockOpts = {
'tmp': {
'lens-cluster-store.json': JSON.stringify({
__internal__: {
migrations: {
version: "2.6.6"
}
},
cluster1: {
kubeConfig: "foo",
icon: "icon path",
preferences: {
terminalCWD: "/tmp"
}
},
})
}
}
mockFs(mockOpts)
})
afterEach(() => {
mockFs.restore()
})
it("adds cluster to default workspace", async () => {
const clusterStore = ClusterStore.getInstance()
const storedClusterData = clusterStore.store.get("clusters")[0]
expect(storedClusterData.workspace).toBe('default')
})
})
+87
View File
@@ -0,0 +1,87 @@
import * as mockFs from "mock-fs"
import * as yaml from "js-yaml"
jest.mock("electron", () => {
return {
app: {
getVersion: () => '99.99.99',
getPath: () => 'tmp',
getLocale: () => 'en'
}
}
})
// Console.log needs to be called before fs-mocks, see https://github.com/tschaub/mock-fs/issues/234
console.log("");
import { userStore, User, UserPreferences, UserStore } from "../../../src/common/user-store"
describe("for an empty config", () => {
beforeEach(() => {
UserStore.resetInstance()
const mockOpts = {
'tmp': {
'config.json': JSON.stringify({})
}
}
mockFs(mockOpts)
const userStore = UserStore.getInstance()
})
afterEach(() => {
mockFs.restore()
})
it("allows setting and retrieving lastSeenAppVersion", async () => {
userStore.setLastSeenAppVersion("1.2.3");
expect(userStore.lastSeenAppVersion()).toBe("1.2.3");
})
it("allows adding and listing seen contexts", async () => {
userStore.storeSeenContext(['foo'])
expect(userStore.getSeenContexts().length).toBe(1)
userStore.storeSeenContext(['foo', 'bar'])
const seenContexts = userStore.getSeenContexts()
expect(seenContexts.length).toBe(2) // check 'foo' isn't added twice
expect(seenContexts[0]).toBe('foo')
expect(seenContexts[1]).toBe('bar')
})
it("allows setting and getting preferences", async () => {
userStore.setPreferences({
httpsProxy: 'abcd://defg',
})
const storedPreferences = userStore.getPreferences()
expect(storedPreferences.httpsProxy).toBe('abcd://defg')
expect(storedPreferences.colorTheme).toBe('dark') // defaults to dark
userStore.setPreferences({
colorTheme: 'light'
})
expect(userStore.getPreferences().colorTheme).toBe('light')
})
})
describe("migrations", () => {
beforeEach(() => {
UserStore.resetInstance()
const mockOpts = {
'tmp': {
'config.json': JSON.stringify({
user: { username: 'foobar' },
preferences: { colorTheme: 'light' },
lastSeenAppVersion: '1.2.3'
})
}
}
mockFs(mockOpts)
const userStore = UserStore.getInstance()
})
afterEach(() => {
mockFs.restore()
})
it("sets last seen app version to 0.0.0", async () => {
expect(userStore.lastSeenAppVersion()).toBe('0.0.0')
})
})
+39
View File
@@ -0,0 +1,39 @@
import { EventEmitter } from 'events'
class MockServer extends EventEmitter {
listen = jest.fn((obj) => {
if(obj.port < 9003) {
this.emit('error', new Error("fail!"))
} else {
this.emit('listening', {})
}
return this
})
unref = jest.fn()
close = jest.fn((cb) => {
cb()
})
}
// eslint-disable-next-line @typescript-eslint/no-var-requires
const net = require("net")
jest.mock("net")
import * as port from "../../../src/main/port"
describe("getFreePort", () => {
beforeEach(() => {
net.createServer.mockReturnValue(new MockServer)
})
afterEach(() => {
jest.clearAllMocks()
})
it("fails for an invalid range", async () => {
return expect(port.getFreePort(1, 2)).rejects.toMatch('free port')
})
it("finds the next free port", async () => {
return expect(port.getFreePort(9000, 9005)).resolves.toBe(9003)
})
})