Skip to content
This repository has been archived by the owner on Oct 23, 2024. It is now read-only.

Commit

Permalink
Merge pull request #18 from NCAR/codecov-workflows
Browse files Browse the repository at this point in the history
Gir release 2 - Josh
  • Loading branch information
JoshHare authored Oct 14, 2024
2 parents a2eaf82 + e58c4a7 commit 253c1fb
Show file tree
Hide file tree
Showing 8 changed files with 224 additions and 2 deletions.
49 changes: 49 additions & 0 deletions .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Codecov Coverage

on:
push:
branches:
- main
- codecov-workflows
pull_request:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest

steps:
# Checkout code
- name: Checkout code
uses: actions/checkout@v2

# Setup .NET environment
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.0.x # Use the version your project requires

# Restore dependencies
- name: Restore dependencies
run: dotnet restore

# Build the project
- name: Build
run: dotnet build --no-restore

# Step 5: Run tests and collect code coverage
- name: Test and calculate coverage
run: |
dotnet test --no-build --verbosity normal \
/p:CollectCoverage=true /p:CoverletOutputFormat=opencover \
/p:CoverletOutput=./TestResults/coverage.opencover.xml
# Step 6: Upload the code coverage report to Codecov
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }} # Add the Codecov token in the GitHub secrets
files: ./TestResults/coverage.opencover.xml # Ensure the correct path for the coverage file
flags: unittests
fail_ci_if_error: true
13 changes: 13 additions & 0 deletions .runsettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="XPlat Code Coverage">
<Configuration>
<Format>opencover</Format>
<OutputDirectory>./TestResults</OutputDirectory>
<Include>[Tests*]*</Include>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
</RunSettings>
11 changes: 11 additions & 0 deletions Chemistry Cafe API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,20 @@
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>.</DockerfileContext>
<PlatformTarget>AnyCPU</PlatformTarget>
<CollectCoverage>true</CollectCoverage>
<CoverletOutputFormat>opencover</CoverletOutputFormat>
<CoverletOutput>../TestResults/</CoverletOutput>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.msbuild" Version="6.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.4" />
<PackageReference Include="Microsoft.CodeCoverage" Version="17.9.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
Expand Down
1 change: 1 addition & 0 deletions chemistry-cafe-database.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ CREATE TABLE `User` (
`uuid` char(38) NOT NULL,
`log_in_info` varchar(1000) DEFAULT NULL,
`isDel` tinyint NOT NULL DEFAULT '0',
`role` ENUM('unverified', 'verified', 'admin') NOT NULL DEFAULT 'unverified',
PRIMARY KEY (`uuid`),
UNIQUE KEY `uuid` (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import './index.css'

const rootElement = document.getElementById('root');
const root = createRoot(rootElement!);

//"534701394161-6gcjh4gd19u5p40gtagdl8i0bkg28rvg.apps.googleusercontent.com" preexisting
//"505816606185-4lkg5cmmod039i5kclktij01ct5in2ug.apps.googleusercontent.com" jmhh
//"257697450661-a69l9bv939uuso551n6pcf1gngpv9ql0.apps.googleusercontent.com"> chemcafe
root.render(
<BrowserRouter>
<GoogleOAuthProvider clientId="534701394161-6gcjh4gd19u5p40gtagdl8i0bkg28rvg.apps.googleusercontent.com">
<GoogleOAuthProvider clientId="505816606185-4lkg5cmmod039i5kclktij01ct5in2ug.apps.googleusercontent.com">
<React.StrictMode>
<App />
</React.StrictMode>
Expand Down
138 changes: 138 additions & 0 deletions frontend/src/webPages/Roles/RoleManagement.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { useEffect, useState } from 'react';
import axios from 'axios';
import Button from '@mui/material/Button';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import Modal from '@mui/material/Modal';
import { Footer } from '../Components/HeaderFooter';

interface User {
id: string;
name: string;
email: string;
role: 'unverified' | 'verified' | 'admin'; // Define the possible roles
}

const RoleManagement = () => {
const [users, setUsers] = useState<User[]>([]);
const [selectedUser, setSelectedUser] = useState<User | null>(null);
const [roleModalOpen, setRoleModalOpen] = useState(false);

const handleRoleModalOpen = (user: User) => {
setSelectedUser(user);
setRoleModalOpen(true);
};

const handleRoleModalClose = () => {
setSelectedUser(null);
setRoleModalOpen(false);
};

// Fetch users from the backend
useEffect(() => {
const fetchUsers = async () => {
try {
const response = await axios.get<User[]>('http://localhost:5173/api/User/all'); // Adjust the endpoint as needed
setUsers(response.data);
} catch (error) {
console.error('Error fetching users:', error);
}
};

fetchUsers();
}, []);

// Update user role
const updateUserRole = async (userId: string, newRole: 'unverified' | 'verified' | 'admin') => {
try {
await axios.patch(`/api/users/${userId}`, { role: newRole }); // Adjust the endpoint as needed
setUsers(prevUsers =>
prevUsers.map(user =>
user.id === userId ? { ...user, role: newRole } : user
)
);
handleRoleModalClose();
} catch (error) {
console.error('Error updating user role:', error);
}
};

const style = {
position: 'absolute' as 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 400,
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
};

return (
<section>
<Box sx={{ width: '100%', maxWidth: 700, mb: 4 }}>
<Typography variant="h2" sx={{ color: 'black' }}>
Role Management
</Typography>
</Box>

<div>
{users.map(user => (
<Box key={user.id} sx={{ bgcolor: '#C3D7EE', padding: 2, marginBottom: 2 }}>
<Typography variant="h6">{user.name}</Typography>
<Typography variant="body1">Email: {user.email}</Typography>
<Typography variant="body2">Role: {user.role}</Typography>
<Button
variant='contained'
onClick={() => handleRoleModalOpen(user)}
sx={{ width: '50%' }}
>
Change Role
</Button>
</Box>
))}
</div>

<Modal open={roleModalOpen} onClose={handleRoleModalClose}>
<Box sx={style}>
<Typography variant="h4">Change Role</Typography>
{selectedUser && (
<>
<Typography variant="body1">User: {selectedUser.name}</Typography>
<Typography variant="body2">Current Role: {selectedUser.role}</Typography>

<Button
variant="contained"
onClick={() => updateUserRole(selectedUser.id, 'verified')}
sx={{ margin: '8px' }}
>
Set to Verified
</Button>
<Button
variant="contained"
onClick={() => updateUserRole(selectedUser.id, 'admin')}
sx={{ margin: '8px' }}
>
Set to Admin
</Button>
<Button
variant="contained"
onClick={() => updateUserRole(selectedUser.id, 'unverified')}
sx={{ margin: '8px' }}
>
Set to Unverified
</Button>
</>
)}
</Box>
</Modal>

<div>
<Footer />
</div>
</section>
);
};

export default RoleManagement;
2 changes: 2 additions & 0 deletions frontend/src/webPages/RoutingRenders/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Settings from '../Settings/settings';
import LoggedIn from '../LogIn/loggedIn';
import FamilyPage from '../Family/family';
import LogIn from '../LogIn/logIn';
import RoleManagement from '../Roles/RoleManagement';

function App() {
return (
Expand All @@ -12,6 +13,7 @@ function App() {
<Route path="/" element={<LogIn />} />
<Route path="/LoggedIn" element={<LoggedIn />} />
<Route path="/FamilyPage" element={<FamilyPage />} />
<Route path="/Roles" element={<RoleManagement />} />
<Route path="/Settings" element={<Settings />} />
</Routes>
</div>
Expand Down
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 253c1fb

Please sign in to comment.