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

atlp-rwanda / champs-ec-fe / e1efb44b-4d95-4788-a87a-75c8af5e5d4d

06 Jul 2024 10:44AM UTC coverage: 85.424% (+1.5%) from 83.95%
e1efb44b-4d95-4788-a87a-75c8af5e5d4d

Pull #46

circleci

tchamianest
Feat(Dashboard): The seller and admin dashboard
Pull Request #46: seller and admin dashboard

217 of 301 branches covered (72.09%)

Branch coverage included in aggregate %.

350 of 361 new or added lines in 14 files covered. (96.95%)

3 existing lines in 2 files now uncovered.

3276 of 3788 relevant lines covered (86.48%)

2.6 hits per line

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

87.5
/src/redux/slices/productSlice.ts
1
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';
1✔
2
import axios from 'axios';
1✔
3
import request from '@/utils/axios';
1✔
4

1✔
5
interface IProduct {
1✔
6
  id: string;
1✔
7
  productName: string;
1✔
8
  productCategory: string;
1✔
9
  productPrice: number;
1✔
10
  discount: number;
1✔
11
  currency: string;
1✔
12
  expireDate: string;
1✔
13
  stockLevel: number;
1✔
14
  description: string;
1✔
15
  loading: false;
1✔
16
  productPictures: File[];
1✔
17
}
1✔
18

1✔
19
interface ICategory {
1✔
20
  id: string;
1✔
21
  categoryName: string;
1✔
22
}
1✔
23

1✔
24
interface ICreateProductInput {
1✔
25
  productName: string;
1✔
26
  productCategory: string;
1✔
27
  productPrice: number;
1✔
28
  discount: number;
1✔
29
  currency: string;
1✔
30
  expireDate: string;
1✔
31
  stockLevel: number;
1✔
32
  description: string;
1✔
33
  productPictures: File[];
1✔
34
}
1✔
35

1✔
36
const URL = process.env.URL;
1✔
37

1✔
38
export const fetchCategories = createAsyncThunk(
1✔
39
  'products/fetchCategories',
1✔
40
  async (_, { rejectWithValue }) => {
1✔
41
    try {
2✔
42
      const response: any = await request.get(`/categories`);
2!
NEW
43
      return response.categories;
×
44
    } catch (error: any) {
2✔
45
      if (error.response && error.response.data.error) {
2✔
46
        return rejectWithValue(error.response.data);
2✔
47
      } else {
2!
48
        return rejectWithValue(error.message);
×
49
      }
×
50
    }
2✔
51
  },
2✔
52
);
1✔
53

1✔
54
export const createProduct = createAsyncThunk(
1✔
55
  'products/createProduct',
1✔
56
  async (data: ICreateProductInput, { rejectWithValue }) => {
1✔
57
    try {
2✔
58
      // const token = localStorage.getItem('token');
2✔
59
      // if (!token) {
2✔
60
      //   throw new Error('No token found');
2✔
61
      // }
2✔
62

2✔
63
      const formData = new FormData();
2✔
64
      formData.append('productName', data.productName);
2✔
65
      formData.append('productCategory', data.productCategory);
2✔
66
      formData.append('productPrice', data.productPrice.toString());
2✔
67
      // formData.append('discount', data.discount.toString());
2✔
68
      formData.append('productCurrency', data.currency.trim());
2✔
69
      formData.append('expireDate', data.expireDate);
2✔
70
      formData.append('stockLevel', data.stockLevel.toString());
2✔
71
      formData.append('productDescription', data.description);
2✔
72
      for (const picture of data.productPictures) {
2!
73
        formData.append('productImage', picture);
×
74
      }
×
75

2✔
76
      const response: any = await request.post(`/products`, formData);
2!
NEW
77
      return response;
×
78
    } catch (error: any) {
2✔
79
      if (error.response && error.response.data) {
2✔
80
        return rejectWithValue(error.response.data);
2✔
81
      } else {
2!
UNCOV
82
        return rejectWithValue(error.message);
×
UNCOV
83
      }
×
84
    }
2✔
85
  },
2✔
86
);
1✔
87

1✔
88
export const productsSlice = createSlice({
1✔
89
  name: 'products',
1✔
90
  initialState: {
1✔
91
    products: [] as IProduct[],
1✔
92
    categories: [] as ICategory[],
1✔
93
    status: 'idle' as string,
1✔
94
    error: null as string | null,
1✔
95
  },
1✔
96
  reducers: {
1✔
97
    addProduct: (state, action: PayloadAction<IProduct>) => {
1✔
98
      state.products.push(action.payload);
×
99
    },
×
100
  },
1✔
101
  extraReducers: (builder) => {
1✔
102
    builder
13✔
103
      .addCase(fetchCategories.pending, (state) => {
13✔
104
        state.status = 'loading';
5✔
105
      })
5✔
106
      .addCase(fetchCategories.fulfilled, (state, action) => {
13✔
107
        state.status = 'succeeded';
2✔
108
        state.categories = action.payload;
2✔
109
      })
2✔
110
      .addCase(fetchCategories.rejected, (state, action) => {
13✔
111
        state.status = 'failed';
2✔
112
        state.error = action.payload as string;
2✔
113
      })
2✔
114
      .addCase(createProduct.pending, (state) => {
13✔
115
        state.status = 'loading';
3✔
116
      })
3✔
117
      .addCase(createProduct.fulfilled, (state, action) => {
13✔
118
        state.status = 'succeeded';
×
119
        state.products.push(action.payload);
×
120
      })
×
121
      .addCase(createProduct.rejected, (state, action) => {
13✔
122
        state.status = 'failed';
2✔
123
        state.error = action.payload as string;
2✔
124
      });
2✔
125
  },
13✔
126
});
1✔
127

1✔
128
export const { addProduct } = productsSlice.actions;
1✔
129
const productsAddReducers = productsSlice.reducer;
1✔
130

1✔
131
export default productsAddReducers;
1✔
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