• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / gui / 897326496

pending completion
897326496

Pull #3752

gitlab-ci

mzedel
chore(e2e): made use of shared timeout & login checking values to remove code duplication

Signed-off-by: Manuel Zedel <manuel.zedel@northern.tech>
Pull Request #3752: chore(e2e-tests): slightly simplified log in test + separated log out test

4395 of 6392 branches covered (68.76%)

8060 of 9780 relevant lines covered (82.41%)

126.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.09
/src/js/components/settings/settings.js
1
// Copyright 2017 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14
import React, { useEffect, useState } from 'react';
15
import { connect } from 'react-redux';
16
import { Navigate, useParams } from 'react-router-dom';
17

18
// material ui
19
import { Payment as PaymentIcon } from '@mui/icons-material';
20

21
import { Elements } from '@stripe/react-stripe-js';
22

23
import { TIMEOUTS } from '../../constants/appConstants';
24
import { versionCompare } from '../../helpers';
25
import { getCurrentUser, getIsEnterprise, getTenantCapabilities, getUserCapabilities, getUserRoles } from '../../selectors';
26
import LeftNav from '../common/left-nav';
27
import SelfUserManagement from '../settings/user-management/selfusermanagement';
28
import UserManagement from '../settings/user-management/usermanagement';
29
import Global from './global';
30
import Integrations from './integrations';
31
import Organization from './organization/organization';
32
import Roles from './roles';
33
import Upgrade from './upgrade';
34

35
let stripePromise = null;
4✔
36

37
const sectionMap = {
4✔
38
  'global-settings': { component: Global, text: () => 'Global settings', canAccess: () => true },
1✔
39
  'my-profile': { component: SelfUserManagement, text: () => 'My profile', canAccess: () => true },
2✔
40
  'organization-and-billing': {
41
    component: Organization,
42
    text: () => 'Organization and billing',
1✔
43
    canAccess: ({ hasMultitenancy }) => hasMultitenancy
1✔
44
  },
45
  'user-management': {
46
    component: UserManagement,
47
    text: () => 'User management',
1✔
48
    canAccess: ({ userCapabilities: { canManageUsers } }) => canManageUsers
1✔
49
  },
50
  'role-management': {
51
    component: Roles,
52
    text: () => 'Roles',
×
53
    canAccess: ({ currentUser, isEnterprise, userRoles: { isAdmin } }) => currentUser && isAdmin && isEnterprise
1✔
54
  },
55
  integrations: {
56
    component: Integrations,
57
    text: () => 'Integrations',
1✔
58
    canAccess: ({ userRoles: { isAdmin }, version }) => isAdmin && versionCompare(version, '3.2') > -1
1✔
59
  },
60
  upgrade: {
61
    component: Upgrade,
62
    icon: <PaymentIcon />,
63
    text: ({ isTrial }) => (isTrial ? 'Upgrade to a plan' : 'Upgrades and add-ons'),
1!
64
    canAccess: ({ hasMultitenancy }) => hasMultitenancy
1✔
65
  }
66
};
67

68
export const Settings = ({ currentUser, hasMultitenancy, isEnterprise, isTrial, stripeAPIKey, tenantCapabilities, userCapabilities, userRoles, version }) => {
4✔
69
  const [loadingFinished, setLoadingFinished] = useState(!stripeAPIKey);
1✔
70
  const { section: sectionParam } = useParams();
1✔
71

72
  useEffect(() => {
1✔
73
    // Make sure to call `loadStripe` outside of a component’s render to avoid recreating
74
    // the `Stripe` object on every render - but don't initialize twice.
75
    if (!stripePromise) {
1!
76
      import(/* webpackChunkName: "stripe" */ '@stripe/stripe-js').then(({ loadStripe }) => {
1✔
77
        if (stripeAPIKey) {
1!
78
          stripePromise = loadStripe(stripeAPIKey).finally(() => setLoadingFinished(true));
×
79
        }
80
      });
81
    } else {
82
      const notStripePromise = new Promise(resolve => setTimeout(resolve, TIMEOUTS.debounceDefault));
×
83
      Promise.race([stripePromise, notStripePromise]).then(result => setLoadingFinished(result !== notStripePromise));
×
84
    }
85
  }, []);
86

87
  const checkDenyAccess = item =>
1✔
88
    currentUser.id && !item.canAccess({ currentUser, hasMultitenancy, isEnterprise, isTrial, tenantCapabilities, userCapabilities, userRoles, version });
8✔
89

90
  const getCurrentSection = (sections, section = sectionParam) => {
1!
91
    if (!sections.hasOwnProperty(section) || checkDenyAccess(sections[section])) {
1!
92
      return;
×
93
    }
94
    return sections[section];
1✔
95
  };
96

97
  const links = Object.entries(sectionMap).reduce((accu, [key, item]) => {
1✔
98
    if (!checkDenyAccess(item)) {
7✔
99
      accu.push({
6✔
100
        path: `/settings/${key}`,
101
        icon: item.icon,
102
        title: item.text({ isTrial })
103
      });
104
    }
105
    return accu;
7✔
106
  }, []);
107

108
  const section = getCurrentSection(sectionMap, sectionParam);
1✔
109
  if (!section) {
1!
110
    return <Navigate to="/settings/my-profile" replace />;
×
111
  }
112
  const Component = section.component;
1✔
113
  return (
1✔
114
    <div className="tab-container with-sub-panels" style={{ minHeight: '95%' }}>
115
      <LeftNav sections={[{ itemClass: 'settingsNav', items: links, title: 'Settings' }]} />
116
      <div className="rightFluid padding-right">
117
        {loadingFinished && (
2✔
118
          <Elements stripe={stripePromise}>
119
            <Component />
120
          </Elements>
121
        )}
122
      </div>
123
    </div>
124
  );
125
};
126

127
const mapStateToProps = state => {
4✔
128
  const { trial: isTrial = false } = state.organization.organization;
1✔
129
  return {
1✔
130
    currentUser: getCurrentUser(state),
131
    hasMultitenancy: state.app.features.hasMultitenancy,
132
    isEnterprise: getIsEnterprise(state),
133
    isTrial,
134
    stripeAPIKey: state.app.stripeAPIKey,
135
    tenantCapabilities: getTenantCapabilities(state),
136
    userCapabilities: getUserCapabilities(state),
137
    userRoles: getUserRoles(state),
138
    version: state.app.versionInformation.Integration
139
  };
140
};
141

142
export default connect(mapStateToProps)(Settings);
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc