Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v1.112.0 - release β†’ staging #10174

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
dea5d57
fix: [M3-7722] - Adjust EditableText styling to prevent pixel shift (…
abailly-akamai Jan 31, 2024
e6d974c
Merge remote-tracking branch 'origin/master' into develop
jaalah Jan 31, 2024
6cf8490
upcoming: [M3-7660] - Cleanup files to use `profile` to get `user_typ…
jaalah-akamai Feb 1, 2024
70b5242
fix: [M3-7728] - Token issues when account switching (#10138)
mjac0bs Feb 1, 2024
1f5650a
Merge pull request #10145 from linode/staging
cpathipa Feb 5, 2024
5354bae
Merge remote-tracking branch 'origin/Master' into develop
cpathipa Feb 5, 2024
460012d
fix: [M3-7725] - Unit tests button enabled assertions (#10142)
abailly-akamai Feb 6, 2024
b847864
Tech Story: [M3-7360] - DC Get Well - Cleanup/Remove feature flag log…
abailly-akamai Feb 6, 2024
a381824
upcoming: [M3-7622] - Create Select component Placement Groups (#10100)
carrillo-erik Feb 6, 2024
418f4f6
test: [M3-7737] - Resolve Billing Contact Cypress failure (#10150)
jdamore-linode Feb 6, 2024
3bb8475
upcoming: [M3-7612] Placement Group Linodes List (#10123)
abailly-akamai Feb 7, 2024
c80abf4
refactor: [M3-7736] - Clean up `regionDropdown` feature flag (#10148)
bnussman-akamai Feb 7, 2024
e33c125
change: [M3-7584] - Update `react-router-dom` in preparation for Reac…
bnussman-akamai Feb 7, 2024
165b5bf
upcoming: [M3-7696] - Edit Access key Drawer - Fix Save button is dis…
cpathipa Feb 7, 2024
ef6d814
refactor: [M3-7582] - Remove Enzyme (#10160)
bnussman-akamai Feb 8, 2024
731a274
test: [M3-7698] - Add test to check proxy user disabled username/emai…
cliu-akamai Feb 8, 2024
49ea132
fix: [M3-7741] - Hide error notices for $0 regions in Resize Pool and…
mjac0bs Feb 8, 2024
b31f6b1
fix: [M3-7746] - Fix $0 region price error in "Enable All Backups" dr…
jdamore-linode Feb 8, 2024
48f3c13
fix: [M3-7004] - Allow IPv6 ranges transfers (#10156)
abailly-akamai Feb 8, 2024
466d3c5
fix: [M3-7747] - Fix Linode Migration dialog hidden $0 price (#10166)
jdamore-linode Feb 9, 2024
e68bbb0
fix: [M3-7739] - Fix error when enabling backups for Linodes in regio…
jdamore-linode Feb 9, 2024
a53f63b
upcoming: [M3-7527] - Improve Login History restricted and child user…
mjac0bs Feb 9, 2024
586a24e
refactor: [M3-7750] - Update `launchdarkly-react-client-sdk` to lates…
bnussman-akamai Feb 9, 2024
c8e291e
test: [M3-7435, M3-7637] - Cypress tests for OBJ Multicluster access …
jdamore-linode Feb 9, 2024
ebc3f76
upcoming: [M3-7726] - Assign Linodes to Placement Group Drawer (#10140)
abailly-akamai Feb 9, 2024
24ed96d
Cloud version 1.112.0
cpathipa Feb 12, 2024
6e53da4
Correct the release version in changelog
cpathipa Feb 12, 2024
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
2 changes: 1 addition & 1 deletion docs/development-guide/08-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Test execution will stop at the debugger statement, and you will be able to use

### React Testing Library

We have some older tests that still use the Enzyme framework, but for new tests we generally use [React Testing Library](https://testing-library.com/docs/react-testing-library/intro). This library provides a set of tools to render React components from within the Vitest environment. The library's philosophy is that components should be tested as closely as possible to how they are used.
This library provides a set of tools to render React components from within the Vitest environment. The library's philosophy is that components should be tested as closely as possible to how they are used.

A simple test using this library will look something like this:

Expand Down
7 changes: 5 additions & 2 deletions packages/api-v4/src/object-storage/objectStorageKeys.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { createObjectStorageKeysSchema } from '@linode/validation/lib/objectStorageKeys.schema';
import {
createObjectStorageKeysSchema,
updateObjectStorageKeysSchema,
} from '@linode/validation/lib/objectStorageKeys.schema';
import { API_ROOT } from '../constants';
import Request, {
setData,
Expand Down Expand Up @@ -51,7 +54,7 @@ export const updateObjectStorageKey = (
Request<ObjectStorageKey>(
setMethod('PUT'),
setURL(`${API_ROOT}/object-storage/keys/${encodeURIComponent(id)}`),
setData(data, createObjectStorageKeysSchema)
setData(data, updateObjectStorageKeysSchema)
);

/**
Expand Down
18 changes: 8 additions & 10 deletions packages/api-v4/src/placement-groups/placement-groups.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import {
assignVMsToPlacementGroupSchema,
createPlacementGroupSchema,
unassignVMsFromPlacementGroupSchema,
renamePlacementGroupSchema,
} from '@linode/validation';
import { API_ROOT } from '../constants';
Expand All @@ -15,10 +13,10 @@ import Request, {
} from '../request';
import type { Filter, Params, ResourcePage as Page } from '../types';
import type {
AssignVMsToPlacementGroupPayload,
AssignLinodesToPlacementGroupPayload,
CreatePlacementGroupPayload,
PlacementGroup,
UnassignVMsFromPlacementGroupPayload,
UnassignLinodesFromPlacementGroupPayload,
RenamePlacementGroupPayload,
} from './types';

Expand Down Expand Up @@ -109,9 +107,9 @@ export const deletePlacementGroup = (placementGroupId: number) =>
*
* @note While this accepts an array of Linode ids (future proofing), only one Linode id is supported at this time.
*/
export const assignVMsToPlacementGroup = (
export const assignLinodesToPlacementGroup = (
placementGroupId: number,
linodeIds: AssignVMsToPlacementGroupPayload
payload: AssignLinodesToPlacementGroupPayload
) =>
Request<PlacementGroup>(
setURL(
Expand All @@ -120,7 +118,7 @@ export const assignVMsToPlacementGroup = (
)}/assign`
),
setMethod('POST'),
setData(linodeIds, assignVMsToPlacementGroupSchema)
setData(payload)
);

/**
Expand All @@ -133,9 +131,9 @@ export const assignVMsToPlacementGroup = (
*
* @note While this accepts an array of Linode ids (future proofing), only one Linode id is supported at this time.
*/
export const unassignVMsFromPlacementGroup = (
export const unassignLinodesFromPlacementGroup = (
placementGroupId: number,
linodeIds: UnassignVMsFromPlacementGroupPayload
payload: UnassignLinodesFromPlacementGroupPayload
) =>
Request<PlacementGroup>(
setURL(
Expand All @@ -144,5 +142,5 @@ export const unassignVMsFromPlacementGroup = (
)}/unassign`
),
setMethod('POST'),
setData(linodeIds, unassignVMsFromPlacementGroupSchema)
setData(payload)
);
8 changes: 6 additions & 2 deletions packages/api-v4/src/placement-groups/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,9 @@ export type RenamePlacementGroupPayload = Pick<PlacementGroup, 'label'>;
/**
* Since the API expects an array of ONE linode id, we'll use a tuple here.
*/
export type AssignVMsToPlacementGroupPayload = [number];
export type UnassignVMsFromPlacementGroupPayload = [number];
export type AssignLinodesToPlacementGroupPayload = {
linodes: [number];
};
export type UnassignLinodesFromPlacementGroupPayload = {
linodes: [number];
};
37 changes: 37 additions & 0 deletions packages/manager/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,43 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).

## [2024-02-12] - v1.112.0


### Fixed:

- EditableText interaction styling ([#10132](https://github.com/linode/manager/pull/10132))
- Unit tests Button enabled assertions ([#10142](https://github.com/linode/manager/pull/10142))
- Error when enabling backups for Linodes in regions with $0 pricing ([#10153](https://github.com/linode/manager/pull/10153))
- Allow IPv6 ranges transfers ([#10156](https://github.com/linode/manager/pull/10156))
- Error notices for $0 regions in LKE Resize and Add Node Pools drawers ([#10157](https://github.com/linode/manager/pull/10157))
- Error in Enable All Backups drawer when one or more Linode is in a $0 region ([#10161](https://github.com/linode/manager/pull/10161))
- Display $0.00 prices in Linode Migration dialog ([#10166](https://github.com/linode/manager/pull/10166))

### Tech Stories:

- DC Get Well - Cleanup/Remove feature flag logic ([#10146](https://github.com/linode/manager/pull/10146))
- Clean up `regionDropdown` feature flag ([#10148](https://github.com/linode/manager/pull/10148))
- Update `react-router-dom` in preparation for React 18 ([#10154](https://github.com/linode/manager/pull/10154))
- Remove Enzyme ([#10160](https://github.com/linode/manager/pull/10160))
- Update `launchdarkly-react-client-sdk` ([#10165](https://github.com/linode/manager/pull/10165))

### Tests:

- Add integration test coverage for Account Login History ([#10125](https://github.com/linode/manager/pull/10125))
- Add test to check proxy user disabled username/email field ([#10139](https://github.com/linode/manager/pull/10139))
- Add Cypress tests for OBJ Multicluster access key operations ([#10144](https://github.com/linode/manager/pull/10144))
- Fix billing contact Cypress test by narrowing element selection scope ([#10150](https://github.com/linode/manager/pull/10150))

### Upcoming Features:

- Create Placement Groups Select component ([#10100](https://github.com/linode/manager/pull/10100))
- Cleanup files to use profile to get user_type ([#10102](https://github.com/linode/manager/pull/10102))
- "Save" button in Edit Access Key drawer disabled unless field values are changed ([#10118](https://github.com/linode/manager/pull/10118))
- Add Placement Group Linodes List ([#10123](https://github.com/linode/manager/pull/10123))
- Improve restricted access Login History experience for child and restricted users ([#10125](https://github.com/linode/manager/pull/10125))
- Add AssignLinodesToPlacementGroup drawer ([#10140](https://github.com/linode/manager/pull/10140))

## [2024-02-05] - v1.111.0
### Changed:

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/**
* @file Integration tests for Cloud Manager account login history flows.
*/

import { accountFactory, profileFactory } from 'src/factories';
import { accountLoginFactory } from 'src/factories/accountLogin';
import { formatDate } from 'src/utilities/formatDate';
import {
mockGetAccount,
mockGetAccountLogins,
} from 'support/intercepts/account';
import {
mockAppendFeatureFlags,
mockGetFeatureFlagClientstream,
} from 'support/intercepts/feature-flags';
import { mockGetProfile } from 'support/intercepts/profile';
import { makeFeatureFlagData } from 'support/util/feature-flags';

describe('Account login history', () => {
/*
* - Confirms that a user can navigate to and view the login history page.
* - Confirms that login table displays the expected column headers.
* - Confirms that the login table displays a mocked failed restricted user login.
* - Confirm that the login table displays a mocked successful unrestricted user login.
*/
it('users can view the login history table', () => {
const mockAccount = accountFactory.build();
const mockProfile = profileFactory.build({
username: 'mock-user',
restricted: false,
user_type: null,
});
const mockFailedLogin = accountLoginFactory.build({
status: 'failed',
username: 'mock-restricted-user',
restricted: true,
});
const mockSuccessfulLogin = accountLoginFactory.build({
status: 'successful',
restricted: false,
});

mockGetAccount(mockAccount).as('getAccount');
mockGetProfile(mockProfile).as('getProfile');
mockGetAccountLogins([mockFailedLogin, mockSuccessfulLogin]).as(
'getAccountLogins'
);

// TODO: Parent/Child - M3-7559 clean up when feature is live in prod and feature flag is removed.
mockAppendFeatureFlags({
parentChildAccountAccess: makeFeatureFlagData(false),
}).as('getFeatureFlags');
mockGetFeatureFlagClientstream().as('getClientStream');

// Navigate to Account Login History page.
cy.visitWithLogin('/account/login-history');
cy.wait([
'@getAccount',
'@getClientStream',
'@getFeatureFlags',
'@getProfile',
]);

// Confirm helper text above table is visible.
cy.findByText(
'Logins across all users on your account over the last 90 days.'
).should('be.visible');

// Confirm the login table includes the expected column headers and mocked logins are visible in table.
cy.findByLabelText('Account Logins').within(() => {
cy.get('thead').findByText('Date').should('be.visible');
cy.get('thead').findByText('Username').should('be.visible');
cy.get('thead').findByText('IP').should('be.visible');
cy.get('thead').findByText('Permission Level').should('be.visible');
cy.get('thead').findByText('Access').should('be.visible');

// Confirm that restricted user's failed login and status icon display in table.
cy.findByText(mockFailedLogin.username)
.should('be.visible')
.closest('tr')
.within(() => {
cy.findByText(mockFailedLogin.status, { exact: false }).should(
'be.visible'
);
cy.findAllByLabelText(`Status is ${mockFailedLogin.status}`);
cy.findByText('Restricted').should('be.visible');
});

// Confirm that unrestricted user login displays in table.
cy.findByText(mockSuccessfulLogin.username)
.should('be.visible')
.closest('tr')
.within(() => {
// Confirm that successful login and status icon display in table.
cy.findByText(mockSuccessfulLogin.status, { exact: false }).should(
'be.visible'
);
cy.findAllByLabelText(`Status is ${mockSuccessfulLogin.status}`);

// Confirm all other fields display in table.
cy.findByText(
formatDate(mockSuccessfulLogin.datetime, {
timezone: mockProfile.timezone,
})
).should('be.visible');
cy.findByText(mockSuccessfulLogin.ip).should('be.visible');
cy.findByText('Unrestricted').should('be.visible');
});
});
});

/**
* - Confirms that a child user can navigate to the Login History page.
* - Confirms that a child user cannot see login history data.
* - Confirms that a child user sees a notice instead.
*/
it('child users cannot view login history', () => {
const mockAccount = accountFactory.build();
const mockProfile = profileFactory.build({
username: 'mock-child-user',
restricted: false,
user_type: 'child',
});

mockGetAccount(mockAccount).as('getAccount');
mockGetProfile(mockProfile).as('getProfile');

// TODO: Parent/Child - M3-7559 clean up when feature is live in prod and feature flag is removed.
mockAppendFeatureFlags({
parentChildAccountAccess: makeFeatureFlagData(true),
}).as('getFeatureFlags');
mockGetFeatureFlagClientstream().as('getClientStream');

// Navigate to Account Login History page.
cy.visitWithLogin('/account/login-history');
cy.wait([
'@getAccount',
'@getClientStream',
'@getFeatureFlags',
'@getProfile',
]);

// Confirm helper text above table and table are not visible.
cy.findByText(
'Logins across all users on your account over the last 90 days.'
).should('not.exist');
cy.findByLabelText('Account Logins').should('not.exist');

cy.findByText(
'Access restricted. Please contact your business partner to request the necessary permission.'
);
});

/**
* - Confirms that a restricted user can navigate to the Login History page.
* - Confirms that a restricted user cannot see login history data.
* - Confirms that a restricted user sees a notice instead.
*/
it('restricted users cannot view login history', () => {
const mockAccount = accountFactory.build();
const mockProfile = profileFactory.build({
username: 'mock-restricted-user',
restricted: true,
user_type: null,
});

mockGetProfile(mockProfile).as('getProfile');
mockGetAccount(mockAccount).as('getAccount');

// TODO: Parent/Child - M3-7559 clean up when feature is live in prod and feature flag is removed.
mockAppendFeatureFlags({
parentChildAccountAccess: makeFeatureFlagData(true),
}).as('getFeatureFlags');
mockGetFeatureFlagClientstream().as('getClientStream');

// Navigate to Account Login History page.
cy.visitWithLogin('/account/login-history');
cy.wait([
'@getAccount',
'@getClientStream',
'@getFeatureFlags',
'@getProfile',
]);

// Confirm helper text above table and table are not visible.
cy.findByText(
'Logins across all users on your account over the last 90 days.'
).should('not.exist');
cy.findByLabelText('Account Logins').should('not.exist');

cy.findByText(
'Access restricted. Please contact your account administrator to request the necessary permission.'
);
});
});
Loading
Loading