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

safe-global / safe-client-gateway / 9846931178

08 Jul 2024 09:06PM UTC coverage: 48.298% (+0.04%) from 48.257%
9846931178

Pull #1740

github

web-flow
Bump docker/setup-qemu-action from 3.0.0 to 3.1.0

Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v3.0.0...v3.1.0)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #1740: Bump docker/setup-qemu-action from 3.0.0 to 3.1.0

414 of 2587 branches covered (16.0%)

Branch coverage included in aggregate %.

4227 of 7022 relevant lines covered (60.2%)

13.11 hits per line

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

11.76
/src/routes/notifications/notifications.service.ts
1
import {
16✔
2
  BadRequestException,
3
  Inject,
4
  Injectable,
5
  InternalServerErrorException,
6
} from '@nestjs/common';
7
import { Device } from '@/domain/notifications/entities/device.entity';
16✔
8
import { SafeRegistration as DomainSafeRegistration } from '@/domain/notifications/entities/safe-registration.entity';
16✔
9
import { INotificationsRepository } from '@/domain/notifications/notifications.repository.interface';
16✔
10
import { RegisterDeviceDto } from '@/routes/notifications/entities/register-device.dto.entity';
11
import { SafeRegistration } from '@/routes/notifications/entities/safe-registration.entity';
12

13
@Injectable()
14
export class NotificationsService {
16✔
15
  constructor(
16
    @Inject(INotificationsRepository)
17
    private readonly notificationsRepository: INotificationsRepository,
16✔
18
  ) {}
19

20
  /**
21
   * Sends a registration request for each {@link DomainSafeRegistration} contained in the received
22
   * {@link RegisterDeviceDto}, instructing the provider to register the {@link Device} as a
23
   * notification target on each chain referenced in one of the {@link DomainSafeRegistration}.
24
   *
25
   * Since the provider requests are made independently, and they could error, the following
26
   * logic is followed to indicate the operation result to the client:
27
   *
28
   * - If no errors occur, HTTP 200 OK is sent to the client.
29
   *
30
   * - If the provider responds at least one server error (HTTP 500..599 code),
31
   *   then HTTP 500 is sent to the client.
32
   *
33
   * - If no server errors but the provider responds at least one client error
34
   *   (HTTP 400..499 code), then HTTP 400 is sent to the client.
35
   *
36
   * - Any other error (or status code not set) is assumed to be mapped to HTTP 503
37
   *   (see {@link HttpErrorFactory}).
38
   *
39
   * @param registerDeviceDto {@link RegisterDeviceDto} containing the data to register
40
   */
41
  async registerDevice(registerDeviceDto: RegisterDeviceDto): Promise<void> {
42
    const device = new Device(
×
43
      registerDeviceDto.uuid,
44
      registerDeviceDto.cloudMessagingToken,
45
      registerDeviceDto.buildNumber,
46
      registerDeviceDto.bundle,
47
      registerDeviceDto.deviceType,
48
      registerDeviceDto.version,
49
      registerDeviceDto.timestamp,
50
    );
51

52
    const { safeRegistrations } = registerDeviceDto;
×
53
    const registrationResults = await Promise.allSettled(
×
54
      safeRegistrations.map((safeRegistration) =>
55
        this.notificationsRepository.registerDevice(
×
56
          device,
57
          new DomainSafeRegistration(
58
            safeRegistration.chainId,
59
            safeRegistration.safes,
60
            safeRegistration.signatures,
61
          ),
62
        ),
63
      ),
64
    );
65

66
    if (registrationResults.some((result) => this.isServerError(result))) {
×
67
      throw new InternalServerErrorException(
×
68
        this.getErrorMessage(registrationResults, safeRegistrations),
69
      );
70
    }
71
    if (registrationResults.some((result) => this.isClientError(result))) {
×
72
      throw new BadRequestException(
×
73
        this.getErrorMessage(registrationResults, safeRegistrations),
74
      );
75
    }
76
  }
77

78
  /**
79
   * Un-registers a device notification target.
80
   * The uuid is expected to be managed by the client. Its value should be equal
81
   * to the one provided when the client called {@link registerDevice}.
82
   */
83
  async unregisterDevice(args: {
84
    chainId: string;
85
    uuid: string;
86
  }): Promise<void> {
87
    return this.notificationsRepository.unregisterDevice(args);
×
88
  }
89

90
  /**
91
   * Un-registers a Safe notification target.
92
   * The uuid is expected to be managed by the client. Its value should be equal
93
   * to the one provided when the client called {@link unregisterSafe}.
94
   */
95
  async unregisterSafe(args: {
96
    chainId: string;
97
    uuid: string;
98
    safeAddress: `0x${string}`;
99
  }): Promise<void> {
100
    return this.notificationsRepository.unregisterSafe(args);
×
101
  }
102

103
  private isServerError(
104
    result: PromiseSettledResult<DomainSafeRegistration>,
105
  ): boolean {
106
    return (
×
107
      result.status === 'rejected' &&
×
108
      result.reason?.code >= 500 &&
×
109
      result.reason?.code < 600
×
110
    );
111
  }
112

113
  private isClientError(
114
    result: PromiseSettledResult<DomainSafeRegistration>,
115
  ): boolean {
116
    return (
×
117
      result.status === 'rejected' &&
×
118
      result.reason?.code >= 400 &&
×
119
      result.reason?.code < 500
×
120
    );
121
  }
122

123
  private getErrorMessage(
124
    registrationResults: PromiseSettledResult<DomainSafeRegistration>[],
125
    safeRegistrations: SafeRegistration[],
126
  ): string {
127
    const successChainIds = (
128
      registrationResults.filter(
×
129
        ({ status }) => status === 'fulfilled',
×
130
      ) as PromiseFulfilledResult<DomainSafeRegistration>[]
131
    ).map((registrationResult) => registrationResult.value.chainId);
×
132

133
    const erroredChainIds = safeRegistrations
×
134
      .map((safeRegistration) => safeRegistration.chainId)
×
135
      .filter((chainId) => !successChainIds.includes(chainId));
×
136

137
    return `Push notification registration failed for chain IDs: ${erroredChainIds}`;
×
138
  }
139
}
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