diff --git a/src/activities/services/activities.service.ts b/src/activities/services/activities.service.ts index 6e3088a..933d32f 100644 --- a/src/activities/services/activities.service.ts +++ b/src/activities/services/activities.service.ts @@ -219,7 +219,6 @@ export class ActivitiesService { params: FindActivitiesInput = {}, currentUser: User = null, ): Promise { - const builder = this.activitiesRepository .createQueryBuilder('ac') .select('EXTRACT(YEAR FROM ac.date)', 'year') @@ -247,7 +246,6 @@ export class ActivitiesService { } as StatsActivities; }); return myStats; - } async find(params: FindActivitiesInput = {}): Promise { @@ -326,7 +324,7 @@ export class ActivitiesService { ActivityRoute, 'ar', 'ar.activity_id = a.id AND (ar."publish" IN (:...publish))', - { publish: ['log', 'public'] }, + { publish: ['public'] }, ); // Allow/disallow based on publishStatus of contained activity routes diff --git a/src/activities/services/activity-routes.service.ts b/src/activities/services/activity-routes.service.ts index 707cdf9..3e158d4 100644 --- a/src/activities/services/activity-routes.service.ts +++ b/src/activities/services/activity-routes.service.ts @@ -646,7 +646,7 @@ export class ActivityRoutesService { if (!currentUser) { // Allow showing only public ascents to guests builder.andWhere('ar."publish" IN (:...publish)', { - publish: ['log', 'public'], + publish: ['public'], }); // Allow showing only published routes (no drafts or in_reviews) @@ -657,7 +657,7 @@ export class ActivityRoutesService { '(ar.user_id = :userId OR ar."publish" IN (:...publish))', { userId: currentUser.id, - publish: ['log', 'public'], + publish: ['public'], }, ); // TODO: should also allow showing club ascents diff --git a/src/crags/crags.module.ts b/src/crags/crags.module.ts index 1bcb273..10b6783 100644 --- a/src/crags/crags.module.ts +++ b/src/crags/crags.module.ts @@ -71,6 +71,10 @@ import { RouteEvent } from './entities/route-event.entity'; import { Parking } from './entities/parking.entity'; import { ParkingsService } from './services/parkings.service'; import { AreaLoader } from './loaders/area.loader'; +import { ActivityRoutesService } from '../activities/services/activity-routes.service'; +import { ActivitiesModule } from '../activities/activities.module'; +import { ClubMember } from '../users/entities/club-member.entity'; +import { Club } from '../users/entities/club.entity'; @Module({ imports: [ @@ -98,7 +102,10 @@ import { AreaLoader } from './loaders/area.loader'; IceFallProperty, StarRatingVote, Parking, + Club, + ClubMember, ]), + forwardRef(() => ActivitiesModule), forwardRef(() => AuditModule), BullModule.registerQueue({ name: 'summary', @@ -148,6 +155,7 @@ import { AreaLoader } from './loaders/area.loader'; CragLoader, RouteLoader, ParkingsService, + ActivityRoutesService, ], controllers: [UploadController], exports: [ diff --git a/src/crags/resolvers/routes.resolver.ts b/src/crags/resolvers/routes.resolver.ts index 1785f06..995f1eb 100644 --- a/src/crags/resolvers/routes.resolver.ts +++ b/src/crags/resolvers/routes.resolver.ts @@ -49,6 +49,11 @@ import { LatestDifficultyVotesInput } from '../dtos/latest-difficulty-votes.inpu import { PaginatedDifficultyVotes } from '../utils/paginated-difficulty-votes'; import { MoveRouteToSectorInput } from '../dtos/move-route-to-sector.input'; import { SectorsService } from '../services/sectors.service'; +import { PaginatedActivityRoutes } from '../../activities/utils/paginated-activity-routes.class'; +import { ActivityRoutesService } from '../../activities/services/activity-routes.service'; +import { FindActivityRoutesInput } from '../../activities/dtos/find-activity-routes.input'; +import { StarRatingVotesService } from '../services/star-rating-votes.service'; +import { StarRatingVote } from '../entities/star-rating-vote.entity'; @Resolver(() => Route) @UseInterceptors(DataLoaderInterceptor) @@ -57,14 +62,18 @@ export class RoutesResolver { private routesService: RoutesService, private sectorsService: SectorsService, private difficultyVotesService: DifficultyVotesService, + private starRatingVotesService: StarRatingVotesService, private entityPropertiesService: EntityPropertiesService, private notificationService: NotificationService, + private activityRoutesService: ActivityRoutesService, ) {} /* QUERIES */ @Query(() => Route) @UseFilters(NotFoundFilter) + @AllowAny() + @UseGuards(UserAuthGuard) async route(@Args('id') id: string): Promise { return this.routesService.findOneById(id); } @@ -251,6 +260,11 @@ export class RoutesResolver { return this.difficultyVotesService.findByRouteId(route.id); } + @ResolveField('starRatingVotes', () => [StarRatingVote]) + async starRatingVotes(@Parent() route: Route): Promise { + return this.starRatingVotesService.findByRouteId(route.id); + } + @ResolveField('crag', () => Crag) async getCrag( @Parent() route: Route, @@ -286,4 +300,17 @@ export class RoutesResolver { ): Promise { return loader.load(route.routeTypeId); } + + @ResolveField('activityRoutes', () => PaginatedActivityRoutes) + @UseGuards(UserAuthGuard) + async activityRoutes( + @Parent() route: Route, + @Args('input', { nullable: true }) input: FindActivityRoutesInput = {}, + @CurrentUser() currentUser: User, + ): Promise { + return this.activityRoutesService.paginate( + { ...input, routeId: route.id }, + currentUser, + ); + } } diff --git a/src/crags/services/star-rating-votes.service.ts b/src/crags/services/star-rating-votes.service.ts index 6f3a1e3..0bea768 100644 --- a/src/crags/services/star-rating-votes.service.ts +++ b/src/crags/services/star-rating-votes.service.ts @@ -18,4 +18,11 @@ export class StarRatingVotesService { .andWhere('srv.route_id IN (:...routeIds)', { routeIds }) .getMany(); } + + async findByRouteId(routeId: string): Promise { + return this.starRatingVoteRepository.find({ + where: { routeId: routeId }, + order: { stars: 'ASC' }, + }); + } } diff --git a/test/e2e/activity.e2e-spec.ts b/test/e2e/activity.e2e-spec.ts index a1579af..ccc7464 100644 --- a/test/e2e/activity.e2e-spec.ts +++ b/test/e2e/activity.e2e-spec.ts @@ -276,7 +276,7 @@ describe('Activity', () => { expect(activitiesIds).not.toContain(mockData.activities.nonCragActivity.id); }); - it('should get only public (or log) activity routes and only activities containing at least one public (or log) activity route when fetching as a guest', async () => { + it('should get only public activity routes and only activities containing at least one public activity route when fetching as a guest', async () => { const response = await request(app.getHttpServer()) .post('/graphql') .send({ @@ -304,14 +304,13 @@ describe('Activity', () => { const numOfNonPublicActivityRoutes = response.body.data.activities.items.filter( (a) => - a.routes.filter((ar) => !['log', 'public'].includes(ar.publish)) - .length > 0, + a.routes.filter((ar) => !['public'].includes(ar.publish)).length > 0, ).length; expect(numOfNonPublicActivityRoutes).toEqual(0); const numOfActivitiesWithNoPublicActivityRoutes = response.body.data.activities.items.filter( - (a) => !a.routes.some((ar) => ['log', 'public'].includes(ar.publish)), + (a) => !a.routes.some((ar) => ['public'].includes(ar.publish)), ).length; expect(numOfActivitiesWithNoPublicActivityRoutes).toEqual(0); @@ -320,7 +319,7 @@ describe('Activity', () => { const returnedActivitiesIds = response.body.data.activities.items.map( (a) => a.id, ); - expect(returnedActivitiesIds).toContain( + expect(returnedActivitiesIds).not.toContain( mockData.activities.activityWithLogRoutes.id, ); expect(returnedActivitiesIds).toContain( @@ -340,7 +339,7 @@ describe('Activity', () => { mockData.activities.activityWithPublicRoutes.activityRoutes .publicActivityRoute.id, ); - expect(returnedActivityRoutesIds).toContain( + expect(returnedActivityRoutesIds).not.toContain( mockData.activities.activityWithLogRoutes.activityRoutes.logActivityRoute .id, ); @@ -348,7 +347,7 @@ describe('Activity', () => { mockData.activities.activityWithMixedRoutes.activityRoutes .publicActivityRoute.id, ); - expect(returnedActivityRoutesIds).toContain( + expect(returnedActivityRoutesIds).not.toContain( mockData.activities.activityWithMixedRoutes.activityRoutes .logActivityRoute.id, );