-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(reservedip): Add reserved ips to redux store MAASENG-2983 (#5427)
- Created types for reserved IPs - Created store slice for reserved IPs - Created reducers for reserved IPs - Created selectors for reserved IPs - Integrated reserved ip table with store - Removed legacy `StaticDHCPLease` type - Refactored `useStaticDHCPLease` to `useReservedIps`, integrated with store - Created util to get node URL from system ID and node type - Deleted legacy `staticDHCPLease` factory - Created `reservedIp` and `reservedIpState` factories - Created `ReservedIp` type - Created `ReservedIpNodeSummary` type
- Loading branch information
Showing
31 changed files
with
904 additions
and
108 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { actions } from "./slice"; | ||
|
||
it("can create an action for fetching reserved IPs", () => { | ||
expect(actions.fetch()).toEqual({ | ||
type: "reservedip/fetch", | ||
meta: { | ||
model: "reservedip", | ||
method: "list", | ||
}, | ||
payload: null, | ||
}); | ||
}); | ||
|
||
it("can create an action for creating a reserved IP", () => { | ||
const params = { | ||
comment: "It's an IP address", | ||
ip: "192.168.0.2", | ||
mac_address: "00:00:00:00:00:00", | ||
subnet: 1, | ||
}; | ||
|
||
expect(actions.create(params)).toEqual({ | ||
type: "reservedip/create", | ||
meta: { | ||
model: "reservedip", | ||
method: "create", | ||
}, | ||
payload: { | ||
params, | ||
}, | ||
}); | ||
}); | ||
|
||
it("can create an action for deleting a reserved IP", () => { | ||
expect(actions.delete(1)).toEqual({ | ||
type: "reservedip/delete", | ||
meta: { | ||
model: "reservedip", | ||
method: "delete", | ||
}, | ||
payload: { | ||
params: { | ||
id: 1, | ||
}, | ||
}, | ||
}); | ||
}); | ||
|
||
it("can create an action for updating a reserved IP", () => { | ||
const params = { | ||
id: 1, | ||
comment: "It's an IP address", | ||
ip: "192.168.0.2", | ||
mac_address: "00:00:00:00:00:00", | ||
subnet: 1, | ||
}; | ||
|
||
expect(actions.update(params)).toEqual({ | ||
type: "reservedip/update", | ||
meta: { | ||
model: "reservedip", | ||
method: "update", | ||
}, | ||
payload: { | ||
params, | ||
}, | ||
}); | ||
}); | ||
|
||
it("can clean up", () => { | ||
expect(actions.cleanup()).toEqual({ | ||
type: "reservedip/cleanup", | ||
}); | ||
}); | ||
|
||
it("can create an action for getting a reserved IP", () => { | ||
expect(actions.get(1)).toEqual({ | ||
type: "reservedip/get", | ||
meta: { | ||
model: "reservedip", | ||
method: "get", | ||
}, | ||
payload: { | ||
params: { | ||
id: 1, | ||
}, | ||
}, | ||
}); | ||
}); |
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 @@ | ||
export { default, actions as reservedIpActions } from "./slice"; |
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,215 @@ | ||
import reducers, { actions } from "./slice"; | ||
|
||
import * as factory from "@/testing/factories"; | ||
|
||
it("should return the initial state", () => { | ||
expect(reducers(undefined, { type: "" })).toEqual( | ||
factory.reservedIpState({ | ||
errors: null, | ||
loading: false, | ||
loaded: false, | ||
items: [], | ||
saved: false, | ||
saving: false, | ||
}) | ||
); | ||
}); | ||
|
||
it("should correctly reduce cleanup", () => { | ||
const initialState = factory.reservedIpState({ | ||
errors: { key: "Key already exists" }, | ||
saved: true, | ||
saving: true, | ||
}); | ||
expect(reducers(initialState, actions.cleanup())).toEqual( | ||
factory.reservedIpState({ | ||
errors: null, | ||
saved: false, | ||
saving: false, | ||
}) | ||
); | ||
}); | ||
|
||
describe("fetch reducers", () => { | ||
it("should correctly reduce fetchStart", () => { | ||
const initialState = factory.reservedIpState({ loading: false }); | ||
expect(reducers(initialState, actions.fetchStart())).toEqual( | ||
factory.reservedIpState({ | ||
loading: true, | ||
}) | ||
); | ||
}); | ||
|
||
it("should correctly reduce fetchSuccess", () => { | ||
const initialState = factory.reservedIpState({ | ||
loading: true, | ||
loaded: false, | ||
items: [], | ||
}); | ||
const items = [factory.reservedIp(), factory.reservedIp()]; | ||
expect(reducers(initialState, actions.fetchSuccess(items))).toEqual( | ||
factory.reservedIpState({ | ||
loading: false, | ||
loaded: true, | ||
items, | ||
}) | ||
); | ||
}); | ||
|
||
it("should correctly reduce fetchError", () => { | ||
const initialState = factory.reservedIpState({ | ||
loading: true, | ||
loaded: false, | ||
items: [], | ||
}); | ||
expect(reducers(initialState, actions.fetchError("Error"))).toEqual( | ||
factory.reservedIpState({ | ||
loading: false, | ||
errors: "Error", | ||
}) | ||
); | ||
}); | ||
}); | ||
|
||
describe("create reducers", () => { | ||
it("should correctly reduce createStart", () => { | ||
const initialState = factory.reservedIpState({ saving: false }); | ||
expect(reducers(initialState, actions.createStart())).toEqual( | ||
factory.reservedIpState({ | ||
saving: true, | ||
}) | ||
); | ||
}); | ||
|
||
it("should correctly reduce createSuccess", () => { | ||
const initialState = factory.reservedIpState({ | ||
saving: true, | ||
saved: false, | ||
}); | ||
|
||
const reservedIp = factory.reservedIp(); | ||
expect( | ||
reducers( | ||
initialState, | ||
actions.createSuccess(factory.reservedIp(reservedIp)) | ||
) | ||
).toEqual( | ||
factory.reservedIpState({ | ||
saving: false, | ||
saved: true, | ||
items: [reservedIp], | ||
}) | ||
); | ||
}); | ||
|
||
it("should correctly reduce createError", () => { | ||
const initialState = factory.reservedIpState({ | ||
saving: true, | ||
saved: false, | ||
}); | ||
expect(reducers(initialState, actions.createError("Error"))).toEqual( | ||
factory.reservedIpState({ | ||
saving: false, | ||
errors: "Error", | ||
}) | ||
); | ||
}); | ||
|
||
it("should correctly reduce createNotify", () => { | ||
const items = [factory.reservedIp(), factory.reservedIp()]; | ||
const initialState = factory.reservedIpState({ | ||
items: [items[0]], | ||
}); | ||
expect(reducers(initialState, actions.createNotify(items[1]))).toEqual( | ||
factory.reservedIpState({ | ||
items, | ||
}) | ||
); | ||
}); | ||
}); | ||
|
||
describe("delete reducers", () => { | ||
it("should correctly reduce deleteStart", () => { | ||
const initialState = factory.reservedIpState({ saving: false }); | ||
expect(reducers(initialState, actions.deleteStart())).toEqual( | ||
factory.reservedIpState({ | ||
saving: true, | ||
}) | ||
); | ||
}); | ||
|
||
it("should correctly reduce deleteSuccess", () => { | ||
const initialState = factory.reservedIpState({ | ||
saving: true, | ||
saved: false, | ||
}); | ||
expect(reducers(initialState, actions.deleteSuccess({ id: 1 }))).toEqual( | ||
factory.reservedIpState({ | ||
saving: false, | ||
saved: true, | ||
}) | ||
); | ||
}); | ||
|
||
it("should correctly reduce deleteError", () => { | ||
const initialState = factory.reservedIpState({ | ||
saving: true, | ||
saved: false, | ||
}); | ||
expect(reducers(initialState, actions.deleteError("Error"))).toEqual( | ||
factory.reservedIpState({ | ||
saving: false, | ||
errors: "Error", | ||
}) | ||
); | ||
}); | ||
|
||
it("should correctly reduce deleteNotify", () => { | ||
const items = [factory.reservedIp(), factory.reservedIp()]; | ||
const initialState = factory.reservedIpState({ | ||
items, | ||
}); | ||
expect( | ||
reducers(initialState, actions.deleteNotify(items[0].id)).items | ||
).toEqual([items[1]]); | ||
}); | ||
}); | ||
|
||
describe("get reducers", () => { | ||
it("should correctly reduce getStart", () => { | ||
const initialState = factory.reservedIpState({ items: [], loading: false }); | ||
expect(reducers(initialState, actions.getStart())).toEqual( | ||
factory.reservedIpState({ | ||
loading: true, | ||
}) | ||
); | ||
}); | ||
|
||
it("should correctly reduce getSuccess", () => { | ||
const newReservedIp = factory.reservedIp(); | ||
const reservedIpState = factory.reservedIpState({ | ||
items: [], | ||
loading: true, | ||
}); | ||
expect( | ||
reducers(reservedIpState, actions.getSuccess(newReservedIp)) | ||
).toEqual( | ||
factory.reservedIpState({ | ||
items: [newReservedIp], | ||
loading: false, | ||
}) | ||
); | ||
}); | ||
|
||
it("should correctly reduce getError", () => { | ||
const initialState = factory.reservedIpState({ | ||
loading: true, | ||
}); | ||
expect(reducers(initialState, actions.getError("Error"))).toEqual( | ||
factory.reservedIpState({ | ||
loading: false, | ||
errors: "Error", | ||
}) | ||
); | ||
}); | ||
}); |
Oops, something went wrong.