Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/axonivy-market/marketplace
Browse files Browse the repository at this point in the history
… into feature/MARP-224-Create-dockerfile-for-deployment-of-marketplace

# Conflicts:
#	marketplace-build/config/nginx/nginx.conf
#	marketplace-build/release/docker-compose.yml
#	marketplace-ui/src/app/auth/auth.service.ts
#	marketplace-ui/src/environments/environment.development.ts
#	marketplace-ui/src/environments/environment.ts
  • Loading branch information
nqhoan-axonivy committed Jul 24, 2024
2 parents 209ddc3 + 79be723 commit 60e4c24
Show file tree
Hide file tree
Showing 24 changed files with 80 additions and 94 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ jobs:
SERVICE_PASSWORD: ${{ secrets.SERVICE_PASSWORD }}
MONGODB_DATABASE: ${{ secrets.MONGODB_DATABASE }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
MARKET_GITHUB_OAUTH_APP_CLIENT_ID: ${{ secrets.MARKET_GITHUB_OAUTH_APP_CLIENT_ID }}
MARKET_GITHUB_OAUTH_APP_CLIENT_SECRET: ${{ secrets.MARKET_GITHUB_OAUTH_APP_CLIENT_SECRET }}
MARKET_JWT_SECRET_KEY: ${{ secrets.MARKET_JWT_SECRET_KEY }}
run: |
sed -i "s/^MONGODB_INITDB_ROOT_USERNAME=.*$/MONGODB_INITDB_ROOT_USERNAME=$ROOT_USERNAME/" $ENV_FILE
sed -i "s/^MONGODB_INITDB_ROOT_PASSWORD=.*$/MONGODB_INITDB_ROOT_PASSWORD=$ROOT_PASSWORD/" $ENV_FILE
Expand All @@ -44,6 +47,9 @@ jobs:
sed -i "s/^SERVICE_MONGODB_USER=.*$/SERVICE_MONGODB_USER=$SERVICE_USERNAME/" $ENV_FILE
sed -i "s/^SERVICE_MONGODB_PASSWORD=.*$/SERVICE_MONGODB_PASSWORD=$SERVICE_PASSWORD/" $ENV_FILE
sed -i "s/^MARKET_GITHUB_TOKEN=.*$/MARKET_GITHUB_TOKEN=$GH_TOKEN/" $ENV_FILE
sed -i "s/^MARKET_GITHUB_OAUTH_APP_CLIENT_ID=.*$/MARKET_GITHUB_OAUTH_APP_CLIENT_ID=$MARKET_GITHUB_OAUTH_APP_CLIENT_ID/" $ENV_FILE
sed -i "s/^MARKET_GITHUB_OAUTH_APP_CLIENT_SECRET=.*$/MARKET_GITHUB_OAUTH_APP_CLIENT_SECRET=$MARKET_GITHUB_OAUTH_APP_CLIENT_SECRET/" $ENV_FILE
sed -i "s/^MARKET_JWT_SECRET_KEY=.*$/MARKET_JWT_SECRET_KEY=$MARKET_JWT_SECRET_KEY/" $ENV_FILE
- name: Build and bring up containers without cache
working-directory: ./marketplace-build
Expand Down
5 changes: 4 additions & 1 deletion marketplace-build/.env
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ SERVICE_MONGODB_USER=
SERVICE_MONGODB_PASSWORD=
SERVICE_MONGODB_DATABASE=
MARKET_GITHUB_TOKEN=
MARKETPLACE_INSTALLATION_URL=
MARKETPLACE_INSTALLATION_URL=
MARKET_GITHUB_OAUTH_APP_CLIENT_ID=
MARKET_GITHUB_OAUTH_APP_CLIENT_SECRET=
MARKET_JWT_SECRET_KEY=
6 changes: 2 additions & 4 deletions marketplace-build/config/nginx/nginx.conf
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
events{}
events {}

http {
# include the default mime.types to map file extensions to MIME types
include /etc/nginx/mime.types;

server {
listen 80;
server_name marketplace;

root /usr/share/nginx/html;

index index.html;

location / {
Expand All @@ -27,4 +25,4 @@ http {
proxy_redirect off;
}
}
}
}
3 changes: 3 additions & 0 deletions marketplace-build/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ services:
- MONGODB_USERNAME=${SERVICE_MONGODB_USER}
- MONGODB_PASSWORD=${SERVICE_MONGODB_PASSWORD}
- MARKET_GITHUB_TOKEN=${MARKET_GITHUB_TOKEN}
- MARKET_GITHUB_OAUTH_APP_CLIENT_ID=${MARKET_GITHUB_OAUTH_APP_CLIENT_ID}
- MARKET_GITHUB_OAUTH_APP_CLIENT_SECRET=${MARKET_GITHUB_OAUTH_APP_CLIENT_SECRET}
- MARKET_JWT_SECRET_KEY=${MARKET_JWT_SECRET_KEY}
build:
context: ../marketplace-service
dockerfile: Dockerfile
Expand Down
5 changes: 4 additions & 1 deletion marketplace-build/release/.env
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ SERVICE_MONGODB_USER=
SERVICE_MONGODB_PASSWORD=
SERVICE_MONGODB_DATABASE=
MARKET_GITHUB_TOKEN=
MARKETPLACE_INSTALLATION_URL=
MARKETPLACE_INSTALLATION_URL=
MARKET_GITHUB_OAUTH_APP_CLIENT_ID=
MARKET_GITHUB_OAUTH_APP_CLIENT_SECRET=
MARKET_JWT_SECRET_KEY=
4 changes: 3 additions & 1 deletion marketplace-build/release/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ services:
- MONGODB_USERNAME=${SERVICE_MONGODB_USER}
- MONGODB_PASSWORD=${SERVICE_MONGODB_PASSWORD}
- MARKET_GITHUB_TOKEN=${MARKET_GITHUB_TOKEN}

- MARKET_GITHUB_OAUTH_APP_CLIENT_ID=${MARKET_GITHUB_OAUTH_APP_CLIENT_ID}
- MARKET_GITHUB_OAUTH_APP_CLIENT_SECRET=${MARKET_GITHUB_OAUTH_APP_CLIENT_SECRET}
- MARKET_JWT_SECRET_KEY=${MARKET_JWT_SECRET_KEY}
volumes:
mongodata:
3 changes: 3 additions & 0 deletions marketplace-build/release/sprint-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ services:
- MONGODB_USERNAME=${SERVICE_MONGODB_USER}
- MONGODB_PASSWORD=${SERVICE_MONGODB_PASSWORD}
- MARKET_GITHUB_TOKEN=${MARKET_GITHUB_TOKEN}
- MARKET_GITHUB_OAUTH_APP_CLIENT_ID=${MARKET_GITHUB_OAUTH_APP_CLIENT_ID}
- MARKET_GITHUB_OAUTH_APP_CLIENT_SECRET=${MARKET_GITHUB_OAUTH_APP_CLIENT_SECRET}
- MARKET_JWT_SECRET_KEY=${MARKET_JWT_SECRET_KEY}
volumes:
mongodata:

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.springframework.hateoas.PagedModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
Expand Down Expand Up @@ -70,12 +71,13 @@ public ResponseEntity<FeedbackModel> findFeedback(@PathVariable("id") String id)

@Operation(summary = "Find all feedbacks by user id and product id")
@GetMapping()
public ResponseEntity<FeedbackModel> findFeedbackByUserIdAndProductId(@RequestParam String userId,
@RequestParam String productId) {
public ResponseEntity<FeedbackModel> findFeedbackByUserIdAndProductId(@RequestParam("userId") String userId,
@RequestParam("productId") String productId) {
Feedback feedback = feedbackService.findFeedbackByUserIdAndProductId(userId, productId);
return ResponseEntity.ok(feedbackModelAssembler.toModel(feedback));
}

@CrossOrigin("*")
@PostMapping
public ResponseEntity<Void> createFeedback(@RequestBody @Valid FeedbackModel feedback,
@RequestHeader(value = "Authorization", required = false) String authorizationHeader) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.axonivy.market.service.JwtService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
Expand All @@ -34,6 +35,7 @@ public OAuth2Controller(GitHubService gitHubService, JwtService jwtService) {
this.jwtService = jwtService;
}

@CrossOrigin("*")
@PostMapping("/github/login")
public ResponseEntity<Object> gitHubLogin(@RequestBody Oauth2AuthorizationCode oauth2AuthorizationCode) {
GitHubAccessTokenResponse tokenResponse = gitHubService.getAccessToken(oauth2AuthorizationCode.getCode(), clientId,
Expand Down
6 changes: 3 additions & 3 deletions marketplace-service/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ market.cors.allowed.origin.maxAge=3600
synchronized.installation.counts.path=/home/data/market-installation.json
market.github.token=${MARKET_GITHUB_TOKEN}
logging.level.org.springframework.security=DEBUG
spring.security.oauth2.client.registration.github.client-id=<replace-with-your-client-id>
spring.security.oauth2.client.registration.github.client-secret=<replace-with-your-client-secret>
jwt.secret=<replace-with-jwt-secret>
spring.security.oauth2.client.registration.github.client-id=${MARKET_GITHUB_OAUTH_APP_CLIENT_ID}
spring.security.oauth2.client.registration.github.client-secret=${MARKET_GITHUB_OAUTH_APP_CLIENT_SECRET}
jwt.secret=${MARKET_JWT_SECRET_KEY}
jwt.expiration=365
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.verify;

@SpringBootTest(properties = { "MONGODB_USERNAME=user", "MONGODB_PASSWORD=password", "MONGODB_HOST=mongoHost",
"MONGODB_DATABASE=product" })
@SpringBootTest(properties = { "MONGODB_USERNAME=user",
"MONGODB_PASSWORD=password", "MONGODB_HOST=mongoHost", "MONGODB_DATABASE=product",
"MARKET_GITHUB_OAUTH_APP_CLIENT_ID=clientId", "MARKET_GITHUB_OAUTH_APP_CLIENT_SECRET=clientSecret",
"MARKET_JWT_SECRET_KEY=jwtSecret" })
class SchedulingTasksTest {

@SpyBean
Expand Down
2 changes: 1 addition & 1 deletion marketplace-ui/src/app/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class AuthService {
private readonly BASE_URL = environment.apiUrl;
private readonly TOKEN_KEY = 'token';
private readonly githubAuthUrl = 'https://github.com/login/oauth/authorize';
private readonly githubAuthCallbackUrl = window.location.host + environment.githubAuthCallbackUrl;
private readonly githubAuthCallbackUrl = window.location.origin + environment.githubAuthCallbackPath;

constructor(
private readonly http: HttpClient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,6 @@ describe('ProductDetailFeedbackComponent', () => {
expect(component).toBeTruthy();
});

it('should initialize feedbacks and star ratings on ngOnInit', () => {
expect(
mockProductFeedbackService.findProductFeedbackOfUser
).toHaveBeenCalled();
expect(mockProductStarRatingService.fetchData).toHaveBeenCalled();
});

it('should render ProductStarRatingPanelComponent and ProductFeedbacksPanelComponent', () => {
const starRatingPanel = fixture.debugElement.query(
By.directive(ProductStarRatingPanelComponent)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
import {
AfterViewInit,
Component,
computed,
inject,
input,
OnInit,
Signal
} from '@angular/core';
import { ProductStarRatingPanelComponent } from './product-star-rating-panel/product-star-rating-panel.component';
import { ShowFeedbacksDialogComponent } from './show-feedbacks-dialog/show-feedbacks-dialog.component';
import { ProductFeedbacksPanelComponent } from './product-feedbacks-panel/product-feedbacks-panel.component';
import { AppModalService } from '../../../../shared/services/app-modal.service';
import { ActivatedRoute, Router } from '@angular/router';
import { ProductFeedbackService } from './product-feedbacks-panel/product-feedback.service';
import { AuthService } from '../../../../auth/auth.service';
import { TranslateModule } from '@ngx-translate/core';
import { ProductStarRatingService } from './product-star-rating-panel/product-star-rating.service';

const MAX_ELEMENTS = 6;

Expand All @@ -31,7 +26,7 @@ const MAX_ELEMENTS = 6;
templateUrl: './product-detail-feedback.component.html',
styleUrls: ['./product-detail-feedback.component.scss']
})
export class ProductDetailFeedbackComponent implements OnInit, AfterViewInit {
export class ProductDetailFeedbackComponent {
isMobileMode = input<boolean>();
isShowBtnMore: Signal<boolean> = computed(() => {
if (
Expand All @@ -46,42 +41,14 @@ export class ProductDetailFeedbackComponent implements OnInit, AfterViewInit {

productFeedbackService = inject(ProductFeedbackService);
appModalService = inject(AppModalService);
private readonly productStarRatingService = inject(ProductStarRatingService);
private readonly authService = inject(AuthService);
private readonly route = inject(ActivatedRoute);
private readonly router = inject(Router);

showPopup!: boolean;

ngOnInit(): void {
this.productFeedbackService.findProductFeedbackOfUser();
this.productStarRatingService.fetchData();
}

ngAfterViewInit(): void {
this.route.queryParams.subscribe(params => {
this.showPopup = params['showPopup'] === 'true';
if (this.showPopup && this.authService.getToken()) {
this.appModalService.openAddFeedbackDialog().then(
() => this.removeQueryParam(),
() => this.removeQueryParam()
);
}
});
}

openShowFeedbacksDialog(): void {
if (this.isMobileMode()) {
this.productFeedbackService.loadMoreFeedbacks();
} else {
this.appModalService.openShowFeedbacksDialog();
}
}

private removeQueryParam(): void {
this.router.navigate([], {
queryParams: { showPopup: null },
queryParamsHandling: 'merge'
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,22 +112,4 @@ describe('ProductFeedbackService', () => {

expect(service.feedbacks()).toEqual([{ content: 'Sorting test', rating: 3, productId: '123' }]);
});

it('should find product feedback of user', () => {
const mockFeedback: Feedback = {
content: 'User feedback',
rating: 5,
productId: '123'
};

authService.getUserId.and.returnValue('user123');
productDetailService.productId.and.returnValue('123');

service.findProductFeedbackOfUser();
const req = httpMock.expectOne('api/feedback?productId=123&userId=user123');
expect(req.request.method).toBe('GET');
req.flush(mockFeedback);

expect(service.userFeedback()).toEqual(mockFeedback);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class ProductFeedbackService {
.pipe(
tap(() => {
this.initFeedbacks();
this.findProductFeedbackOfUser();
this.findProductFeedbackOfUser().subscribe();
this.productStarRatingService.fetchData();
})
);
Expand Down Expand Up @@ -96,13 +96,13 @@ export class ProductFeedbackService {

findProductFeedbackOfUser(
productId: string = this.productDetailService.productId()
): void {
): Observable<Feedback> {
const params = new HttpParams()
.set('productId', productId)
.set('userId', this.authService.getUserId() ?? '');
const requestURL = FEEDBACK_API_URL;

this.http
return this.http
.get<Feedback>(requestURL, {
params,
context: new HttpContext().set(SkipLoading, true)
Expand All @@ -120,8 +120,7 @@ export class ProductFeedbackService {
this.userFeedback.set(feedback);
return of(feedback);
})
)
.subscribe();
);
}

initFeedbacks(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ <h5 class="text-secondary">
<p class="text-secondary mb-2">
{{ 'common.feedback.starRatingTitle' | translate }}
</p>
<app-star-rating [rate]="feedback.rating" (rateChange)="onRateChange($event)" [starClass]="'adding-feedback-star'" />
<app-star-rating [rate]="feedback.rating" (rateChange)="onRateChange($event)" [starClass]="'adding-feedback-star'" [ratingStarsClass]="'rating-stars'" />
<p class="text-secondary mb-2 mt-3">
{{ 'common.feedback.commentLabel' | translate }}
</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { HttpClient } from '@angular/common/http';
import { HttpClient, HttpContext } from '@angular/common/http';
import {
computed,
inject,
Expand All @@ -10,6 +10,7 @@ import {
import { tap } from 'rxjs';
import { StarRatingCounting } from '../../../../../shared/models/star-rating-counting.model';
import { ProductDetailService } from '../../product-detail.service';
import { SkipLoading } from '../../../../../core/interceptors/api.interceptor';

@Injectable({
providedIn: 'root'
Expand All @@ -29,7 +30,7 @@ export class ProductStarRatingService {
fetchData(productId: string = this.productDetailService.productId()): void {
const requestURL = `api/feedback/product/${productId}/rating`;
this.http
.get<StarRatingCounting[]>(requestURL)
.get<StarRatingCounting[]>(requestURL, {context: new HttpContext().set(SkipLoading, true)})
.pipe(
tap(data => {
this.sortByStar(data);
Expand Down
Loading

0 comments on commit 60e4c24

Please sign in to comment.