Pact JVM posiada wsparcie dla Springa od do艣膰 dawna, ale po stronie dostawcy us艂ugi by艂o ono niestety ograniczone tylko do mockowanego Spring MVC. Pocz膮wszy od wersji 4.7.1, Pact wspiera r贸wnie偶 endpointy Spring WebFlux. W tym artykule zademonstruj臋 u偶ycie Pact Consumer Driven Contracts do testowania serwis贸w wykonanych za pomoc膮 Spring WebFlux oraz konsument贸w tych us艂ug. Zaczn臋 od kr贸tkiego wprowadzenia do Consumer Driven Contract Testing i Spring WebFlux. Nast臋pnie wyja艣ni臋, jak po艂膮czy膰 te dwie technologie, aby utworzy膰 kontrakt i zweryfikowa膰 za jego pomoc膮 zar贸wno konsumenta (consumer), jak i dostawc臋 (provider) us艂ugi.

Czym jest Pact Consumer Driven Contract Testing

Consumer Driven Contract Testing to wzorzec wykorzystywany w testowaniu kompatybilno艣ci pomi臋dzy konsumentami (consumer) i dostawcami (provider) serwis贸w. Og贸lna idea jest taka, 偶e pomi臋dzy tymi dwoma systemami istnieje kontrakt opisuj膮cy zachodz膮ce mi臋dzy nimi interakcje. Je偶eli obydwa systemy wype艂niaj膮 jego za艂o偶enia, test ko艅czy si臋 powodzeniem. Podej艣cie 鈥濩onsumer driven鈥 oznacza, 偶e si艂膮 nap臋dow膮 ewolucji kontraktu s膮 konsumenci serwisu, a nie dostawca.

Wsparciem dla Consumer Contract Testing jest zestaw framework贸w DiUS Pact. Frameworki te koncentruj膮 si臋 g艂贸wnie na komunikacji HTTP, cho膰 dla niekt贸rych platform dost臋pne jest r贸wnie偶 wsparcie dla kolejek. Obecnie implementacje pokrywaj膮 wi臋kszo艣膰 popularnych 艣rodowisk uruchomieniowych, takich jak JVM, .NET, JavaScript czy Ruby.

Czym jest Spring WebFlux

Spring WebFlux to reaktywny framework webowy wprowadzony w Springu 5. Jest to odpowiednik dobrze znanego Spring MVC, z t膮 r贸偶nic膮, 偶e opiera si臋 na nieblokuj膮cym API dostarczanym przez reactive streams. WebFlux jest w stanie obs艂ugiwa膰 du偶e obci膮偶enia na ma艂ej liczbie w膮tk贸w, co skutkuje mniejszym zu偶yciem zasob贸w sprz臋towych.

WebFlux oferuje dwa modele programowania:

  • adnotowane kontrolery
  • endpointy funkcyjne

Pact obs艂uguje oba modele, natomiast dla potrzeb tego artyku艂u skupi臋 si臋 na endpointach funkcyjnych.

Pact i WebFlux 鈥 jak to dzia艂a razem

Poniewa偶 to na kliencie spoczywa odpowiedzialno艣膰 za dostarczanie kontraktu, testy Pact pisane s膮 najpierw dla niego. Ka偶dy z test贸w zawiera opis interakcji pomi臋dzy klientem i dostawc膮, np. requesty i spodziewane odpowiedzi HTTP. Maj膮c te dane, pact framework uruchomi tymczasowy serwer HTTP zwracaj膮cy predefiniowane odpowiedzi i wykona testy klienta.

Niejako efektem ubocznym wykonania testu jest utworzenie pliku kontraktu. Ten sam plik zostanie p贸藕niej u偶yty do sprawdzenia, czy dostawca serwisu spe艂nia za艂o偶enia kontraktu. Po stronie serwera Pact wykona testy, u偶ywaj膮c request贸w zapisanych w kontrakcie i zweryfikuje poprawno艣膰 odpowiedzi. Mo偶emy tutaj dokona膰 wyboru, czy chcemy przetestowa膰 serwis jako ca艂o艣膰, czy tylko jego wycinek odpowiedzialny za komunikacj臋 HTTP. W tym artykule opisz臋 ten drugi przypadek.

Test dla klienta

Za艂贸偶my, 偶e dostawca udost臋pnia endpoint HTTP. Odpowiada on na 偶膮dania HTTP GET, zwracaj膮c JSONa reprezentuj膮cego kolekcj臋 obiekt贸w Foo. U偶yjmy frameworka Spock do zakodowania pact-testu klienta.

Najpierw zdefiniujmy pakt w sekcji given naszego testu. Wykorzystajmy do tego celu klas臋 ConsumerPactBuilder, kt贸r膮 udost臋pnia biblioteka Pact:

[java]given:
def pact = ConsumerPactBuilder.consumer(„consumerService”)
.hasPactWith(„providerService”)
.uponReceiving(„sample request”)
.method(„GET”)
.path(„/foo”)
.willRespondWith()
.status(200)
.headers([„Content-Type”: „application/json”])
.body(„””
[
{„id:” 1, „name”: „Foo”},
{„id”: 2, „name”: „Bar”}
]
„””.stripIndent())
.toPact()[/java]

Widzimy tutaj, 偶e 聽kontakt definiuje interakcje nazwan膮 sample request pomi臋dzy klientem o nazwie consumerService i dostawc膮 providerService. W reakcji na 偶膮danie b臋d膮ce wywo艂aniem metody HTTP GET na 艣cie偶ce /foo, dostawca powinien odpowiedzie膰 statusem HTTP 200, a w sekcji body odpowiedzi powinny by膰 dostarczone reprezentacje dw贸ch obiekt贸w Foo.

Zakodujmy teraz cz臋艣膰 z asercjami oraz wywo艂aniem naszego klienta w sekcji when:

[java]when:
def result = ConsumerPactRunnerKt.runConsumerTest(
pact, MockProviderConfig.createDefault()) { mockServer, context ->

def webClient = WebClient.create(mockServer.getUrl())
def consumerAdapter = new ConsumerAdapter(webClient)

def resultFlux = consumerAdapter.invokeProvider()

StepVerifier.create(resultFlux)
.expectNext(new Foo(1l, 鈥欶oo鈥))
.expectNext(new Foo(2l, 鈥欱ar鈥))
.verifyComplete()
}[/java]

Do wykonania testu klienta u偶yjemy klasy ConsumerPactRunnerKt dostarczanej przez bibliotek臋 Pact. Metoda runConsumerTest, przed wykonaniem kodu z domkni臋cia, uruchomi tymczasowy serwer, kt贸ry b臋dzie odpowiada膰 na 偶膮dania HTTP zdefiniowane wcze艣niej w pakcie. Zapisze r贸wnie偶 kontrakt w postaci pliku JSON, kt贸ry b臋dzie wsp贸艂dzielony z dostawc膮 us艂ugi. Ostatnim z parametr贸w tej metody b臋dzie blok kodu zawieraj膮cy wywo艂anie napisanego przez nas klienta serwisu. W tym przypadku utworzymy reaktywnego webClienta i przeka偶emy mu URL utworzonego przez Pact serwera HTTP. Nast臋pnie stworzymy instancj臋 naszego adaptera (ConsumerAdapter), na kt贸rej wywo艂amy metod臋 invokeProvider() odpowiedzialn膮 za interakcj臋 HTTP z dostawc膮. Poniewa偶 wynikiem tej interakcji b臋dzie Flux do zbadania jej poprawno艣ci, mo偶emy u偶y膰 StepVerifiera z projektu Reactor.

Ostatni膮 faz膮 b臋dzie sprawdzenie w sekcji then, czy weryfikacja kontraktu si臋 powiod艂a:

[java]then:
result instanceof PactVerificationResult.Ok[/java]

To w艂a艣nie tutaj mo偶emy sprawdzi膰, czy StepVerifier nie wygenerowa艂 wyj膮tku (b臋dzie on owini臋ty w klasie PactVerificationResult.Error) lub jaka艣 opisana w kontakcie interakcja nie zosta艂a wywo艂ana lub by艂a z nim niezgodna.

Napiszmy teraz kod przyk艂adowego klienta wykorzystywanego w te艣cie. B臋dzie to standardowy przypadek u偶ycia reaktywnego webClienta do odczytu danych z endpointu /foo:

[java]public Flux<Foo> invokeProvider() {
return webClient
.get()
.uri("/foo")
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToFlux(Foo.class);
}[/java]

Jeste艣my teraz gotowi do wykonania testu. Uruchomi on dostarczany przez framework serwer HTTP 鈥 wywo艂a go, u偶ywaj膮c nale偶膮cej do klienta klasy adaptera, a nast臋pnie zweryfikuje odpowiedzi. Dodatkowo Pact utworzy w katalogu build/pacts plik JSON b臋d膮cy reprezentacj膮 paktu. Plik ten nale偶y nast臋pnie udost臋pni膰 testom kontraktu providera serwisu.

Test dla dostawcy

Poniewa偶 mamy ju偶 gotowy plik kontraktu, test dla providera serwisu b臋dzie nieco bardziej zwi臋z艂y. Tym razem u偶yjemy frameworku JUnit, poniewa偶 Spockowy wzorzec given-when-then nie by艂by tutaj zbyt pomocny:

[java]@RunWith(RestPactRunner.class)
@Provider("providerService")
@PactFolder("pacts")
public class ProviderRouterPactTest {

@TestTarget
public WebFluxTarget target = new WebFluxTarget();

private ProviderHandler handler = new ProviderHandler();
private RouterFunction<ServerResponse> routerFunction
= new ProviderRouter(handler).routes();

@Before
public void setup() {
target.setRouterFunction(routerFunction);
}
}[/java]

Jak mo偶emy zauwa偶y膰, kod nie zawiera 偶adnych metod testowych. Dzieje si臋 tak dlatego, 偶e testowane wywo艂ania i asercje s膮 ju偶 obecne w pliku kontraktu. RestPactRunner (wskazany w adnotacji @RunWith) u偶yje tego pliku i zajmie si臋 wykonaniem przypadk贸w testowych w nim opisanych oraz weryfikacj膮 odpowiedzi. Musimy jeszcze poinformowa膰 runnera o lokalizacji kontrakt贸w (w tym przypadku poprzez adnotacj臋 @PactFolder wskazujemy katalog na dysku) i nazwie dostawcy (za pomoc膮 adnotacji @Provider). Nazwa ta jest o tyle istotna, 偶e silnik Pactu b臋dzie wybiera膰 kontrakty do przetestowania, por贸wnuj膮c j膮 z nazw膮 podan膮 w te艣cie klienta jako .hasPactWith(„providerService”). Adnotacja @TestTarget jest odpowiedzialna za wskazanie celu do testowania. Dla endpoint贸w WebFluxowych b臋dzie to instancja WebFluxTarget. Nale偶y w niej ustawi膰 ju偶 bezpo艣rednio routerFunction, kt贸rej u偶ywamy w kodzie dostawcy. Wygodnym miejscem do zrobienia tego jest tutaj metoda setup() testu.

Nale偶y jeszcze wspomnie膰 o klasach ProviderHandler oraz ProviderRouter. S膮 to elementy implementacji przyk艂adowego dostawcy. Router jest odpowiedzialny za budowanie instancji RouterFunction, kt贸re wi膮偶膮 艣cie偶ki URL z kodem handlera:

[java]@Configuration
@RequiredArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
class ProviderRouter {

ProviderHandler handler;

@Bean
RouterFunction<ServerResponse> routes() {
return route()
.GET("/foo", accept(APPLICATION_JSON), handler::getFoo)
.build();
}

}[/java]

Natomiast metoda handler::getFoo z powy偶szego przyk艂adu jest odpowiedzialna za zwracanie Mono zawieraj膮cego odpowied藕 dostawcy:

[java]Mono<ServerResponse> getFoo(ServerRequest request) {
return ServerResponse
.ok()
.contentType(APPLICATION_JSON)
.body(Flux.just(
new Foo(1l, "Foo"),
new Foo(2l, "Bar")
), Foo.class);
}[/java]

Handler zwraca tutaj dwa obiekty Foo tak jak jest to okre艣lone w kontakcie mi臋dzy dostawc膮 a klientem.

Uruchomienie testu dla dostawcy b臋dzie teraz skutkowa膰 wczytaniem pliku kontraktu, dopasowaniem odpowiedniego dla 艣cie偶ki HTTP handlera, wywo艂aniem go i weryfikacj膮, czy odpowied藕 systemu jest zgodna z t膮 okre艣lon膮 w kontrakcie.

Podsumowanie

Pact Consumer Driven Contracts to bardzo przydatne narz臋dzie do zapewniania sp贸jno艣ci pomi臋dzy elementami z艂o偶onego systemu. Z pewno艣ci膮 jego zalet膮 jest szeroki wachlarz wspieranych technologii, kt贸ry pozwala na testowanie oparte na kontraktach w heterogenicznym 艣rodowisku. Teraz do tego spektrum do艂膮czy艂 kolejny element 鈥 technologia Spring WebFlux, dzi臋ki czemu zyskali艣my mo偶liwo艣膰 wykonywania test贸w wzgl臋dem reaktywnych dostawc贸w.

Kod 藕r贸d艂owy przyk艂ad贸w u偶ytych w tym artykule jest dost臋pny w repozytorium Githuba.

殴r贸d艂a

Pu艂apki wsp贸艂bie偶no艣ci. Narzut synchronizacji w膮tk贸w.

Czy programowanie wsp贸艂bie偶ne ma jakie艣 ciemne strony? Dlaczego warto robi膰 pomiary?
Lucjan 艁yczak z katowickiego .NET pod膮偶a tropem pu艂apek wsp贸艂bie偶no艣ci. Co odkrywa po przeprowadzeniu test贸w wydajno艣ci? Przeczytaj artyku艂 na JPro Tech i dowiedz si臋 wi臋cej!

Przeczytaj artyku艂

Autorem wpisu jest:
Java Developer

Java Developer w JCommerce. Stawia na jako艣膰 rozwi膮za艅 poprzez stosowanie wieloaspektowych technik testowania. Kontrybutor DiUS Pact JVM.

Dodaj komentarz

Skontaktuj si臋 z nami

Chcesz dowiedzie膰 si臋 wi臋cej o naszych us艂ugach? Napisz do nas 鈥 odpowiemy na ka偶d膮 wiadomo艣膰.

    Niniejszym wyra偶am zgod臋 na przetwarzanie przez JCommerce Sp. z o.o. moich danych osobowych (dalej 鈥瀌ane osobowe鈥), takich jak: imi臋 i nazwisko, adres e-mail, nr telefonu, firma, w celach handlowych.
    Niniejszym wyra偶am zgod臋 na przetwarzanie przez JCommerce Sp. z o.o. moich danych osobowych (dalej 鈥瀌ane osobowe鈥), takich jak: imi臋 i nazwisko, adres e-mail, nr telefonu, firma, w celach marketingowych.
    Niniejszym wyra偶am zgod臋 na przetwarzanie przez JCommerce Sp. z o.o. moich danych osobowych (dalej 鈥瀌ane osobowe鈥), takich jak: imi臋 i nazwisko, adres e-mail, nr telefonu, firma w celach rekrutacyjnych.
    Niniejszym wyra偶am zgod臋 na przetwarzanie przez JCommerce Sp. z o.o. moich danych osobowych (dalej 鈥瀌ane osobowe鈥), takich jak: imi臋 i nazwisko, adres e-mail, nr telefonu, firma na potrzeby przysz艂ych rekrutacji.
    W zwi膮zku z obowi膮zuj膮cymi przepisami dotycz膮cymi ochrony danych osobowych tj. Ustaw膮 o ochronie danych osobowych z dnia 10 maja 2018 roku, jak r贸wnie偶 tre艣ci膮 Rozporz膮dzenia Parlamentu Europejskiego i Rady (UE) 2016/679 z dnia 27 kwietnia 2016 r. w sprawie ochrony os贸b fizycznych w zwi膮zku z przetwarzaniem danych osobowych i w sprawie swobodnego przep艂ywu takich danych oraz uchylenia dyrektywy 95/46/WE (RODO), informujemy, 偶e: 1. Administratorem danych osobowych jest JCommerce Sp. z o.o. z siedzib膮 w Katowicach, ul. 艢ciegiennego 3, 40-114 Katowice (KRS: 00007393418).
    2. Powy偶sze dane osobowe przetwarzane b臋d膮 przez JCommerce Sp. z o.o. 鈥 w zale偶no艣ci od udzielonych przez Pani膮/Pana zg贸d (podstawa prawna przetwarzania: art. 6 ust. 1 pkt a) RODO):
    鈥 w celach handlowych,
    鈥 w celach marketingowych,
    鈥 w celach rekrutacyjnych;
    鈥 w celach przysz艂ych rekrutacji.
    3. Podanie powy偶szych danych osobowych nie jest wymogiem ustawowym, umownym lub warunkiem zawarcia umowy. Nie jest Pan/Pani zobowi膮zany/a do podania powy偶szych danych osobowych, jednak brak ich podania uniemo偶liwi realizacje ww. celu.
    4. Posiada Pan/ Pani prawo dost臋pu do tre艣ci swoich danych, w tym otrzymania ich kopii i ich sprostowania, usuni臋cia, ograniczenia przetwarzania, prawo do przenoszenia danych, prawo do sprzeciwu wobec przetwarzania, prawo do cofni臋cia zgody w dowolnym momencie, je艣li zosta艂a udzielona. Wycofanie zgody nie wp艂ywa jednak na zgodno艣膰 z prawem przetwarzania, kt贸rego dokonano na podstawie zgody przed jej wycofaniem; o艣wiadczenie o cofni臋ciu zgody na przetwarzanie danych osobowych nale偶y z艂o偶y膰 w siedzibie JCommerce Sp. z o.o. lub przes艂a膰 na adres mailowy zgody@jcommerce.pl. Cofni臋cie zgody na przetwarzanie danych osobowych skutkuje brakiem mo偶liwo艣ci realizacji ww. cel贸w przetwarzania;
    5. Dane osobowe s膮 udost臋pniane przez JCommerce Sp. z o.o. upowa偶nionym pracownikom i osobom wsp贸艂pracuj膮cym z JCommerce Sp. z o.o. na podstawie um贸w cywilnoprawnych, przez kt贸rych realizowany jest cel przetwarzania;
    6. Wszelkie pytania dotycz膮ce ochrony danych osobowych oraz realizacje przys艂uguj膮cych praw, prosimy kierowa膰 na adres odo@jcommerce.pl;
    7. W zale偶no艣ci od udzielonej zgody, dane osobowe b臋d膮 przetwarzane przez czas niezb臋dny do realizacji ww. cel贸w przetwarzania. W przypadku wniesienia sprzeciwu, JCommerce Sp. z o.o. przestanie przetwarza膰 Pani/Pana dane w ww. celu, chyba 偶e b臋dzie w stanie wykaza膰, 偶e w stosunku do tych danych istniej膮 wa偶ne prawnie uzasadnione podstawy, kt贸re s膮 nadrz臋dne wobec Pana/Pani interes贸w, praw i wolno艣ci, lub niezb臋dne do ewentualnego ustalenia, dochodzenia lub obrony roszcze艅;
    8. Nie przekazujemy Pani/Pana danych poza teren Europejskiego Obszaru Gospodarczego oraz do organizacji mi臋dzynarodowych.
    9. Pani/Pana dane osobowe nie podlegaj膮 zautomatyzowanemu podejmowaniu decyzji, w tym profilowaniu.
    10. Ma Pani/Pan prawo wniesienia skargi do organu nadzorczego gdy uzna Pan/Pani, i偶 przetwarzanie ww. danych osobowych narusza przepisy og贸lnego rozporz膮dzenia o ochronie danych osobowych z dnia 27 kwietnia 2016 r.
    Niniejszym wyra偶am zgod臋 na przetwarzanie przez JCommerce Sp. z o.o. moich danych osobowych (dalej 鈥瀌ane osobowe鈥), takich jak: imi臋 i nazwisko, adres e-mail, nr telefonu, firma, w celach handlowych.
    Niniejszym wyra偶am zgod臋 na przetwarzanie przez JCommerce Sp. z o.o. moich danych osobowych (dalej 鈥瀌ane osobowe鈥), takich jak: imi臋 i nazwisko, adres e-mail, nr telefonu, firma, w celach marketingowych.
    Niniejszym wyra偶am zgod臋 na przetwarzanie przez JCommerce Sp. z o.o. moich danych osobowych (dalej 鈥瀌ane osobowe鈥), takich jak: imi臋 i nazwisko, adres e-mail, nr telefonu, firma w celach rekrutacyjnych.
    Niniejszym wyra偶am zgod臋 na przetwarzanie przez JCommerce Sp. z o.o. moich danych osobowych (dalej 鈥瀌ane osobowe鈥), takich jak: imi臋 i nazwisko, adres e-mail, nr telefonu, firma na potrzeby przysz艂ych rekrutacji.
    W zwi膮zku z obowi膮zuj膮cymi przepisami dotycz膮cymi ochrony danych osobowych tj. Ustaw膮 o ochronie danych osobowych z dnia 10 maja 2018 roku, jak r贸wnie偶 tre艣ci膮 Rozporz膮dzenia Parlamentu Europejskiego i Rady (UE) 2016/679 z dnia 27 kwietnia 2016 r. w sprawie ochrony os贸b fizycznych w zwi膮zku z przetwarzaniem danych osobowych i w sprawie swobodnego przep艂ywu takich danych oraz uchylenia dyrektywy 95/46/WE (RODO), informujemy, 偶e: 1. Administratorem danych osobowych jest JCommerce Sp. z o.o. z siedzib膮 w Katowicach, ul. 艢ciegiennego 3, 40-114 Katowice (KRS: 00007393418).
    2. Powy偶sze dane osobowe przetwarzane b臋d膮 przez JCommerce Sp. z o.o. 鈥 w zale偶no艣ci od udzielonych przez Pani膮/Pana zg贸d (podstawa prawna przetwarzania: art. 6 ust. 1 pkt a) RODO):
    鈥 w celach handlowych,
    鈥 w celach marketingowych,
    鈥 w celach rekrutacyjnych;
    鈥 w celach przysz艂ych rekrutacji.
    3. Podanie powy偶szych danych osobowych nie jest wymogiem ustawowym, umownym lub warunkiem zawarcia umowy. Nie jest Pan/Pani zobowi膮zany/a do podania powy偶szych danych osobowych, jednak brak ich podania uniemo偶liwi realizacje ww. celu.
    4. Posiada Pan/ Pani prawo dost臋pu do tre艣ci swoich danych, w tym otrzymania ich kopii i ich sprostowania, usuni臋cia, ograniczenia przetwarzania, prawo do przenoszenia danych, prawo do sprzeciwu wobec przetwarzania, prawo do cofni臋cia zgody w dowolnym momencie, je艣li zosta艂a udzielona. Wycofanie zgody nie wp艂ywa jednak na zgodno艣膰 z prawem przetwarzania, kt贸rego dokonano na podstawie zgody przed jej wycofaniem; o艣wiadczenie o cofni臋ciu zgody na przetwarzanie danych osobowych nale偶y z艂o偶y膰 w siedzibie JCommerce Sp. z o.o. lub przes艂a膰 na adres mailowy zgody@jcommerce.pl. Cofni臋cie zgody na przetwarzanie danych osobowych skutkuje brakiem mo偶liwo艣ci realizacji ww. cel贸w przetwarzania;
    5. Dane osobowe s膮 udost臋pniane przez JCommerce Sp. z o.o. upowa偶nionym pracownikom i osobom wsp贸艂pracuj膮cym z JCommerce Sp. z o.o. na podstawie um贸w cywilnoprawnych, przez kt贸rych realizowany jest cel przetwarzania;
    6. Wszelkie pytania dotycz膮ce ochrony danych osobowych oraz realizacje przys艂uguj膮cych praw, prosimy kierowa膰 na adres odo@jcommerce.pl;
    7. W zale偶no艣ci od udzielonej zgody, dane osobowe b臋d膮 przetwarzane przez czas niezb臋dny do realizacji ww. cel贸w przetwarzania. W przypadku wniesienia sprzeciwu, JCommerce Sp. z o.o. przestanie przetwarza膰 Pani/Pana dane w ww. celu, chyba 偶e b臋dzie w stanie wykaza膰, 偶e w stosunku do tych danych istniej膮 wa偶ne prawnie uzasadnione podstawy, kt贸re s膮 nadrz臋dne wobec Pana/Pani interes贸w, praw i wolno艣ci, lub niezb臋dne do ewentualnego ustalenia, dochodzenia lub obrony roszcze艅;
    8. Nie przekazujemy Pani/Pana danych poza teren Europejskiego Obszaru Gospodarczego oraz do organizacji mi臋dzynarodowych.
    9. Pani/Pana dane osobowe nie podlegaj膮 zautomatyzowanemu podejmowaniu decyzji, w tym profilowaniu.
    10. Ma Pani/Pan prawo wniesienia skargi do organu nadzorczego gdy uzna Pan/Pani, i偶 przetwarzanie ww. danych osobowych narusza przepisy og贸lnego rozporz膮dzenia o ochronie danych osobowych z dnia 27 kwietnia 2016 r.