mirror of https://github.com/abpframework/abp.git
committed by
GitHub
4 changed files with 162 additions and 19 deletions
@ -0,0 +1,30 @@ |
|||||
|
# Internet Connection Service |
||||
|
`InternetConnectionService` is a service which is exposed by the `@abp/ng.core` package. **You can use this service in order to check your internet connection** |
||||
|
|
||||
|
## Getting Started |
||||
|
When you inject the InternetConnectionService you can get the current internet status, and it gets immediately updated if the status changes. |
||||
|
|
||||
|
`InternetConnectionService` provides two choices to catch the network status: |
||||
|
1. Signal (readonly) |
||||
|
2. Observable |
||||
|
|
||||
|
|
||||
|
# How To Use |
||||
|
İt's easy, just inject the service and get the network status. |
||||
|
|
||||
|
**You can get via signal** |
||||
|
```ts |
||||
|
class SomeComponent{ |
||||
|
internetConnectionService = inject(InternetConnectionService); |
||||
|
isOnline = this.internetConnectionService.networkStatus |
||||
|
} |
||||
|
``` |
||||
|
**or you can get the observable** |
||||
|
```ts |
||||
|
class SomeComponent{ |
||||
|
internetConnectionService = inject(InternetConnectionService); |
||||
|
isOnline = this.internetConnectionService.networkStatus$ |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
To see how we implement to the template, check the `InternetConnectionStatusComponent` |
||||
@ -1,18 +1,32 @@ |
|||||
import { DOCUMENT } from '@angular/common'; |
import { DOCUMENT } from '@angular/common'; |
||||
import { Injectable, inject } from '@angular/core'; |
import { Injectable, computed, inject, signal } from '@angular/core'; |
||||
import { fromEvent, merge, of } from 'rxjs'; |
import { BehaviorSubject } from 'rxjs'; |
||||
import { map } from 'rxjs/operators'; |
|
||||
|
|
||||
@Injectable({ |
@Injectable({ |
||||
providedIn: 'root', |
providedIn: 'root', |
||||
}) |
}) |
||||
export class InternetConnectionService{ |
export class InternetConnectionService{ |
||||
protected readonly window = inject(DOCUMENT).defaultView; |
readonly document = inject(DOCUMENT) |
||||
protected readonly navigator = this.window.navigator; |
readonly window = this.document.defaultView; |
||||
|
readonly navigator = this.window.navigator; |
||||
|
|
||||
networkStatus$ = merge( |
private status$ = new BehaviorSubject<boolean>(this.navigator.onLine) |
||||
of(navigator.onLine), |
|
||||
fromEvent(window, 'offline'), |
private status = signal(this.navigator.onLine); |
||||
fromEvent(window, 'online') |
|
||||
).pipe(map(() => navigator.onLine)) |
networkStatus = computed(() => this.status()) |
||||
|
|
||||
|
constructor(){ |
||||
|
this.window.addEventListener('offline', () => this.setStatus(false)); |
||||
|
this.window.addEventListener('online', () => this.setStatus(true)); |
||||
|
} |
||||
|
|
||||
|
setStatus(val:boolean){ |
||||
|
this.status.set(val) |
||||
|
this.status$.next(val) |
||||
|
} |
||||
|
|
||||
|
get networkStatus$(){ |
||||
|
return this.status$.asObservable() |
||||
|
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,100 @@ |
|||||
|
import { TestBed} from '@angular/core/testing'; |
||||
|
import { DOCUMENT } from '@angular/common'; |
||||
|
|
||||
|
import { InternetConnectionService } from '../services/internet-connection-service'; |
||||
|
import { first } from 'rxjs'; |
||||
|
|
||||
|
let service: InternetConnectionService; |
||||
|
|
||||
|
describe('Internet connection when disconnected', () => { |
||||
|
const events = {}; |
||||
|
const addEventListener = jest.fn((event, callback) => { |
||||
|
events[event] = callback; |
||||
|
}); |
||||
|
const mockDocument = { defaultView: {navigator: {onLine: false}, addEventListener } } |
||||
|
beforeAll(() => { |
||||
|
TestBed.configureTestingModule({ |
||||
|
providers:[{provide:DOCUMENT, useValue: mockDocument}] |
||||
|
}) |
||||
|
service = TestBed.inject(InternetConnectionService); |
||||
|
}); |
||||
|
|
||||
|
it('document should be created', () => { |
||||
|
expect(service.document).toEqual(mockDocument); |
||||
|
}); |
||||
|
|
||||
|
it('signal value should be false', () => { |
||||
|
expect(service.networkStatus()).toEqual(false); |
||||
|
}); |
||||
|
|
||||
|
it('observable value should be false', |
||||
|
(done: any) => { |
||||
|
service.networkStatus$.pipe(first()).subscribe(value => { |
||||
|
expect(value).toBe(false) |
||||
|
done(); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
test.each(['offline','online'])('should addEventListener for %p, event',(v)=>{ |
||||
|
expect(events[v]).toBeTruthy() |
||||
|
}) |
||||
|
|
||||
|
test.each([['offline',false],["online",true]])('when %p called ,then signal value must be %p',(eventName,value)=>{ |
||||
|
events[eventName]() |
||||
|
expect(service.networkStatus()).toEqual(value); |
||||
|
}) |
||||
|
|
||||
|
test.each([['offline',false],["online",true]])('when %p called,then observable must return %p',(eventName,value)=>{ |
||||
|
events[eventName]() |
||||
|
service.networkStatus$.subscribe(val=>{ |
||||
|
expect(val).toEqual(value) |
||||
|
}) |
||||
|
}) |
||||
|
}); |
||||
|
|
||||
|
describe('when connection value changes for signals', () => { |
||||
|
const events = {}; |
||||
|
const addEventListener = jest.fn((event, callback) => { |
||||
|
events[event] = callback; |
||||
|
}); |
||||
|
const mockDocument = { defaultView: {navigator: {onLine: false}, addEventListener } } |
||||
|
beforeAll(() => { |
||||
|
TestBed.configureTestingModule({ |
||||
|
providers:[{provide:DOCUMENT, useValue: mockDocument}] |
||||
|
}) |
||||
|
service = TestBed.inject(InternetConnectionService); |
||||
|
}); |
||||
|
|
||||
|
it('signal value must be false when offline event is called while internet is connected', () => { |
||||
|
events['online']() |
||||
|
expect(service.networkStatus()).toEqual(true); |
||||
|
events['offline']() |
||||
|
expect(service.networkStatus()).toEqual(false); |
||||
|
}); |
||||
|
|
||||
|
it('signal value must be true when online event is called while internet is disconnected', () => { |
||||
|
events['offline']() |
||||
|
expect(service.networkStatus()).toEqual(false); |
||||
|
events['online']() |
||||
|
expect(service.networkStatus()).toEqual(true); |
||||
|
}); |
||||
|
|
||||
|
it('observable value must be false when offline event is called while internet is connected', (done:any) => { |
||||
|
events['online']() |
||||
|
events['offline']() |
||||
|
service.networkStatus$.subscribe(val=>{ |
||||
|
expect(val).toEqual(false) |
||||
|
done() |
||||
|
}) |
||||
|
}); |
||||
|
|
||||
|
it('observable value must be true when online event is called while internet is disconnected', (done:any) => { |
||||
|
events['offline']() |
||||
|
events['online']() |
||||
|
service.networkStatus$.subscribe(val=>{ |
||||
|
console.log(val); |
||||
|
expect(val).toEqual(true) |
||||
|
done() |
||||
|
}) |
||||
|
}); |
||||
|
}); |
||||
Loading…
Reference in new issue